├── .gitignore
├── src
└── main
│ ├── webapp
│ ├── META-INF
│ │ ├── MANIFEST.MF
│ │ └── context.xml
│ └── WEB-INF
│ │ └── web.xml
│ └── java
│ └── com
│ └── zufar
│ └── testtask
│ ├── model
│ ├── Priority.java
│ ├── Identified.java
│ ├── Doctor.java
│ ├── Patient.java
│ └── Prescription.java
│ ├── dao
│ ├── CrudDao.java
│ ├── ConnectionManager.java
│ └── AbstractCrudDao.java
│ ├── hsqldb
│ ├── DaoFactory.java
│ ├── dto
│ │ └── PersonFullName.java
│ ├── PatientDao.java
│ ├── DoctorDao.java
│ └── PrescriptionDao.java
│ └── ui
│ ├── MainUI.java
│ ├── window
│ ├── AbstractWindow.java
│ ├── DoctorWindow.java
│ ├── PatientWindow.java
│ └── PrescriptionWindow.java
│ └── layout
│ ├── AbstractVerticalLayout.java
│ ├── PatientVerticalLayout.java
│ ├── DoctorVerticalLayout.java
│ └── PrescriptionVerticalLayout.java
├── db.properties
├── README.md
├── db.script
└── pom.xml
/.gitignore:
--------------------------------------------------------------------------------
1 | .idea
2 | target/
3 | *.iml
4 | *.ipr
5 | *.iws
--------------------------------------------------------------------------------
/src/main/webapp/META-INF/MANIFEST.MF:
--------------------------------------------------------------------------------
1 | Manifest-Version: 1.0
2 | Class-Path:
3 |
4 |
--------------------------------------------------------------------------------
/src/main/webapp/META-INF/context.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/src/main/java/com/zufar/testtask/model/Priority.java:
--------------------------------------------------------------------------------
1 | package com.zufar.testtask.model;
2 |
3 | public enum Priority {
4 | NORMAL, SITO, STATIM;
5 | }
6 |
--------------------------------------------------------------------------------
/src/main/java/com/zufar/testtask/model/Identified.java:
--------------------------------------------------------------------------------
1 | package com.zufar.testtask.model;
2 |
3 | public interface Identified {
4 |
5 | Id getId();
6 |
7 | void setId(Id id);
8 | }
--------------------------------------------------------------------------------
/db.properties:
--------------------------------------------------------------------------------
1 | #HSQL Database Engine 2.3.4
2 | #Fri Jul 14 13:23:13 SAMT 2017
3 | version=2.3.4
4 | modified=yes
5 | tx_timestamp=0
6 | readonly=false
7 | files_readonly=true
8 | hsqldb.lock_file=false
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Test Task
2 | =========
3 |
4 | Prerequisites
5 | -------------
6 |
7 | * [Java Development Kit (JDK) 8](http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html)
8 | * [Maven 3](https://maven.apache.org/download.cgi)
9 |
10 | Build and Run
11 | -------------
12 |
13 | 1. Run in the command line:
14 | ```
15 | mvn package
16 | mvn jetty:run
17 | ```
18 |
19 | 2. Open `http://localhost:8080` in a web browser.
20 |
--------------------------------------------------------------------------------
/src/main/java/com/zufar/testtask/dao/CrudDao.java:
--------------------------------------------------------------------------------
1 | package com.zufar.testtask.dao;
2 |
3 | import com.zufar.testtask.model.Identified;
4 |
5 | import java.sql.SQLException;
6 | import java.util.List;
7 |
8 | public interface CrudDao, Id> {
9 |
10 | /* Создает запись в БД, соответствующую обьекту object */
11 | void create(E object) throws SQLException;
12 |
13 | /* Возвращает обьект, соответствующий данному идентификатору */
14 | E get(Id id) throws SQLException;
15 |
16 | /* Возвращает список обьектов, соответствующим всем записям в БД */
17 | List getAll() throws SQLException;
18 |
19 | /* Изменяет запись в БД в соответствии с состоянием object */
20 | void update(E object) throws SQLException;
21 |
22 | /* Удаляет запись в БД, соответствующую обьекту object*/
23 | void delete(E object) throws SQLException;
24 |
25 | }
--------------------------------------------------------------------------------
/src/main/java/com/zufar/testtask/hsqldb/DaoFactory.java:
--------------------------------------------------------------------------------
1 | package com.zufar.testtask.hsqldb;
2 |
3 | import com.zufar.testtask.dao.ConnectionManager;
4 |
5 | import java.sql.SQLException;
6 |
7 | public class DaoFactory {
8 |
9 | private static DaoFactory instance = null;
10 |
11 | private DaoFactory() {
12 | }
13 |
14 | public static DaoFactory getInstance() {
15 | if (instance == null) {
16 | instance = new DaoFactory();
17 | }
18 | return instance;
19 | }
20 |
21 | public DoctorDao getDoctorDao() throws SQLException{
22 | return new DoctorDao(ConnectionManager.getConnection());
23 | }
24 |
25 | public PatientDao getPatientDao() throws SQLException {
26 | return new PatientDao(ConnectionManager.getConnection());
27 | }
28 |
29 | public PrescriptionDao getPrescriptionDao() throws SQLException {
30 | return new PrescriptionDao(ConnectionManager.getConnection());
31 | }
32 | }
--------------------------------------------------------------------------------
/src/main/java/com/zufar/testtask/dao/ConnectionManager.java:
--------------------------------------------------------------------------------
1 | package com.zufar.testtask.dao;
2 |
3 | import java.sql.Connection;
4 | import java.sql.DriverManager;
5 | import java.sql.SQLException;
6 |
7 | public class ConnectionManager {
8 |
9 | private static Connection connection = null;
10 |
11 | private ConnectionManager() {
12 | }
13 |
14 | public static Connection getConnection() throws SQLException {
15 | if (connection == null) {
16 | final String user = "SA";
17 | final String password = "";
18 | final String url = "jdbc:hsqldb:file:db";
19 | final String driver = "org.hsqldb.jdbc.JDBCDriver";
20 | try {
21 | Class.forName(driver);
22 | } catch (Exception e) {
23 | throw new SQLException("Problems with getting a connection to the database object!");
24 | }
25 | connection = DriverManager.getConnection(url, user, password);
26 | }
27 | return connection;
28 | }
29 | }
--------------------------------------------------------------------------------
/src/main/java/com/zufar/testtask/hsqldb/dto/PersonFullName.java:
--------------------------------------------------------------------------------
1 | package com.zufar.testtask.hsqldb.dto;
2 |
3 | import com.zufar.testtask.model.Identified;
4 |
5 | public class PersonFullName implements Identified {
6 |
7 | private Long id;
8 | private String firstName;
9 | private String lastName;
10 | private String patronymic;
11 |
12 | public PersonFullName(
13 | Long id,
14 | String firstName,
15 | String lastName,
16 | String patronymic
17 | ) {
18 | this.id = id;
19 | this.firstName = firstName;
20 | this.lastName = lastName;
21 | this.patronymic = patronymic;
22 | }
23 |
24 | public String getPatronymic() {
25 | return patronymic;
26 | }
27 |
28 | public void setPatronymic( String patronymic) {
29 | this.patronymic = patronymic;
30 | }
31 |
32 | @Override
33 | public Long getId() {
34 | return id;
35 | }
36 |
37 | @Override
38 | public void setId(Long id) {
39 | this.id = id;
40 | }
41 |
42 | @Override
43 | public String toString() {
44 | return lastName + " " + firstName + " " + patronymic;
45 | }
46 | }
--------------------------------------------------------------------------------
/src/main/webapp/WEB-INF/web.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 | Vaadin Web Application
7 |
8 | Vaadin production mode
9 | productionMode
10 | false
11 |
12 |
13 | Vaadin Application Servlet
14 | com.vaadin.server.VaadinServlet
15 |
16 | Vaadin UI to display
17 | UI
18 | com.zufar.testtask.ui.MainUI
19 |
20 |
21 |
22 | Vaadin Application Servlet
23 | /*
24 |
25 |
--------------------------------------------------------------------------------
/src/main/java/com/zufar/testtask/ui/MainUI.java:
--------------------------------------------------------------------------------
1 | package com.zufar.testtask.ui;
2 |
3 | import com.zufar.testtask.ui.layout.DoctorVerticalLayout;
4 | import com.zufar.testtask.ui.layout.PatientVerticalLayout;
5 | import com.zufar.testtask.ui.layout.PrescriptionVerticalLayout;
6 | import com.vaadin.annotations.Theme;
7 | import com.vaadin.annotations.Title;
8 | import com.vaadin.server.VaadinRequest;
9 | import com.vaadin.ui.themes.ValoTheme;
10 | import com.vaadin.ui.*;
11 |
12 | @Title("Hospital")
13 | @Theme(ValoTheme.THEME_NAME)
14 | public class MainUI extends UI {
15 |
16 | private DoctorVerticalLayout dctorVerticalLayout = new DoctorVerticalLayout();
17 | private PatientVerticalLayout patientVerticalLayout = new PatientVerticalLayout();
18 | private PrescriptionVerticalLayout prescriptionVerticalLayout = new PrescriptionVerticalLayout();
19 |
20 | @Override
21 | protected void init(VaadinRequest request) {
22 | VerticalLayout rootVerticalLayout = new VerticalLayout(
23 | dctorVerticalLayout,
24 | patientVerticalLayout,
25 | prescriptionVerticalLayout
26 | );
27 | setContent(rootVerticalLayout);
28 | rootVerticalLayout.setMargin(true);
29 | }
30 |
31 | public PrescriptionVerticalLayout getPrescriptionVerticalLayout() {
32 | return prescriptionVerticalLayout;
33 | }
34 | }
--------------------------------------------------------------------------------
/src/main/java/com/zufar/testtask/ui/window/AbstractWindow.java:
--------------------------------------------------------------------------------
1 | package com.zufar.testtask.ui.window;
2 |
3 | import com.zufar.testtask.ui.MainUI;
4 | import com.vaadin.server.FontAwesome;
5 | import com.vaadin.ui.*;
6 |
7 | abstract class AbstractWindow extends Window {
8 |
9 | Button cancelButton = new Button("Cancel", event -> close());
10 | Button okButton = new Button("Ok", this::actionAfterClickOkButton);
11 | VerticalLayout verticalFields = new VerticalLayout();
12 |
13 | AbstractWindow() {
14 | commonActions();
15 | }
16 |
17 | abstract void actionAfterClickOkButton(Button.ClickEvent clickEvent);
18 |
19 | private void commonActions() {
20 | verticalFields.setSpacing(true);
21 | verticalFields.setMargin(true);
22 | center();
23 | setModal(true);
24 | setSizeUndefined();
25 | HorizontalLayout buttonsLayout = new HorizontalLayout(okButton, cancelButton);
26 | buttonsLayout.setSpacing(true);
27 | VerticalLayout verticalMain = new VerticalLayout(verticalFields, buttonsLayout);
28 | verticalMain.setMargin(true);
29 | verticalMain.setComponentAlignment(buttonsLayout, Alignment.MIDDLE_CENTER);
30 | setContent(verticalMain);
31 |
32 | okButton.setEnabled(false);
33 | cancelButton.setEnabled(true);
34 |
35 | cancelButton.setIcon(FontAwesome.CLOSE);
36 | okButton.setIcon(FontAwesome.CHECK);
37 |
38 | okButton.setWidth(String.valueOf(120));
39 | cancelButton.setWidth(String.valueOf(120));
40 | }
41 |
42 | @Override
43 | public MainUI getUI() {
44 | return (MainUI) super.getUI();
45 | }
46 | }
--------------------------------------------------------------------------------
/src/main/java/com/zufar/testtask/ui/layout/AbstractVerticalLayout.java:
--------------------------------------------------------------------------------
1 | package com.zufar.testtask.ui.layout;
2 |
3 | import com.zufar.testtask.ui.MainUI;
4 | import com.vaadin.server.FontAwesome;
5 | import com.vaadin.ui.*;
6 |
7 | abstract class AbstractVerticalLayout extends VerticalLayout {
8 |
9 | Grid grid = new Grid();
10 | Label label = new Label();
11 | Button addButton = new Button();
12 | Button editButton = new Button();
13 | Button deleteButton = new Button("Delete", this::actionAfterClickDeleteButton);
14 | HorizontalLayout buttonsLayout = new HorizontalLayout();
15 |
16 | AbstractVerticalLayout() {
17 | configureCommonComponents();
18 | }
19 |
20 | abstract void actionAfterClickDeleteButton(Button.ClickEvent event);
21 |
22 | private void configureCommonComponents() {
23 | addComponents(label, grid, buttonsLayout);
24 | buttonsLayout.addComponents(addButton, editButton, deleteButton);
25 | buttonsLayout.setSpacing(true);
26 | buttonsLayout.setMargin(true);
27 | addButton.setCaption("Add");
28 | editButton.setCaption("Edit");
29 | addButton.setEnabled(true);
30 | grid.setSizeFull();
31 | grid.setSelectionMode(Grid.SelectionMode.SINGLE);
32 | configureComponentsWidth();
33 | configureComponentsIcons();
34 | }
35 |
36 | private void configureComponentsWidth() {
37 | addButton.setWidth("150");
38 | editButton.setWidth("150");
39 | deleteButton.setWidth("150");
40 | }
41 |
42 | private void configureComponentsIcons() {
43 | addButton.setIcon(FontAwesome.PLUS);
44 | editButton.setIcon(FontAwesome.EDIT);
45 | deleteButton.setIcon(FontAwesome.TRASH);
46 | }
47 |
48 | @Override
49 | public MainUI getUI() {
50 | return (MainUI) super.getUI();
51 | }
52 | }
--------------------------------------------------------------------------------
/src/main/java/com/zufar/testtask/model/Doctor.java:
--------------------------------------------------------------------------------
1 | package com.zufar.testtask.model;
2 |
3 | public class Doctor implements Identified {
4 |
5 | private Long id;
6 | private String firstName;
7 | private String lastName;
8 | private String patronymic;
9 | private String specialization;
10 |
11 | public Doctor(
12 | String firstName,
13 | String lastName,
14 | String patronymic,
15 | String specialization
16 | ) {
17 | this.firstName = firstName;
18 | this.lastName = lastName;
19 | this.patronymic = patronymic;
20 | this.specialization = specialization;
21 | }
22 |
23 | public Doctor() {
24 | }
25 |
26 | public String getFirstName() {
27 | return firstName;
28 | }
29 |
30 | public void setFirstName(String firstName) {
31 | this.firstName = firstName;
32 | }
33 |
34 | public String getLastName() {
35 | return lastName;
36 | }
37 |
38 | public void setLastName(String lastName) {
39 | this.lastName = lastName;
40 | }
41 |
42 | public String getPatronymic() {
43 | return patronymic;
44 | }
45 |
46 | public void setPatronymic(String patronymic) {
47 | this.patronymic = patronymic;
48 | }
49 |
50 | public String getSpecialization() {
51 | return specialization;
52 | }
53 |
54 | public void setSpecialization(String specialization) {
55 | this.specialization = specialization;
56 | }
57 |
58 | @Override
59 | public Long getId() {
60 | return id;
61 | }
62 |
63 | @Override
64 | public void setId(Long primaryKey) {
65 | this.id = primaryKey;
66 | }
67 |
68 | @Override
69 | public String toString() {
70 | return this.firstName + " " + this.lastName + " " + this.patronymic + " " + this.specialization;
71 | }
72 | }
--------------------------------------------------------------------------------
/src/main/java/com/zufar/testtask/model/Patient.java:
--------------------------------------------------------------------------------
1 | package com.zufar.testtask.model;
2 |
3 | public class Patient implements Identified {
4 |
5 | private Long id;
6 | private String firstName;
7 | private String lastName;
8 | private String patronymic;
9 | private Long telephoneNumber;
10 |
11 | public Patient() {
12 | }
13 |
14 | public Patient(
15 | String firstName,
16 | String lastName,
17 | String patronymic,
18 | Long telephoneNumber
19 | ) {
20 | this.firstName = firstName;
21 | this.lastName = lastName;
22 | this.patronymic = patronymic;
23 | this.telephoneNumber = telephoneNumber;
24 | }
25 |
26 | public String getFirstName() {
27 | return firstName;
28 | }
29 |
30 | public void setFirstName(String firstName) {
31 | this.firstName = firstName;
32 | }
33 |
34 | public String getLastName() {
35 | return lastName;
36 | }
37 |
38 | public void setLastName(String lastName) {
39 | this.lastName = lastName;
40 | }
41 |
42 | public String getPatronymic() {
43 | return patronymic;
44 | }
45 |
46 | public void setPatronymic(String patronymic) {
47 | this.patronymic = patronymic;
48 | }
49 |
50 | public Long getTelephoneNumber() {
51 | return telephoneNumber;
52 | }
53 |
54 | public void setTelephoneNumber(Long telephoneNumber) {
55 | this.telephoneNumber = telephoneNumber;
56 | }
57 |
58 | @Override
59 | public Long getId() {
60 | return id;
61 | }
62 |
63 | @Override
64 | public void setId(Long primaryKey) {
65 | this.id = primaryKey;
66 | }
67 |
68 | @Override
69 | public String toString() {
70 | return this.firstName + " " + this.lastName + " " + this.patronymic + " " + this.telephoneNumber;
71 | }
72 | }
--------------------------------------------------------------------------------
/src/main/java/com/zufar/testtask/model/Prescription.java:
--------------------------------------------------------------------------------
1 | package com.zufar.testtask.model;
2 |
3 | import com.zufar.testtask.hsqldb.dto.PersonFullName;
4 |
5 | import java.time.LocalDate;
6 |
7 | public class Prescription implements Identified {
8 |
9 | private Long id;
10 | private String description;
11 | private PersonFullName patient;
12 | private PersonFullName doctor;
13 | private LocalDate creationDate;
14 | private Long validity;
15 | private Priority priority;
16 |
17 | public Prescription(
18 | Long id,
19 | String description,
20 | PersonFullName patientFullName,
21 | PersonFullName doctorFullName,
22 | LocalDate creationDate,
23 | Long validity,
24 | Priority priority
25 | ) {
26 | this.id = id;
27 | this.description = description;
28 | this.patient = patientFullName;
29 | this.doctor = doctorFullName;
30 | this.creationDate = creationDate;
31 | this.validity = validity;
32 | this.priority = priority;
33 | }
34 |
35 | public Prescription(
36 | String description,
37 | PersonFullName patientFullName,
38 | PersonFullName doctorFullName,
39 | LocalDate creationDate,
40 | Long validity,
41 | Priority priority
42 | ) {
43 | this.description = description;
44 | this.patient = patientFullName;
45 | this.doctor = doctorFullName;
46 | this.creationDate = creationDate;
47 | this.validity = validity;
48 | this.priority = priority;
49 | }
50 |
51 | public String getDescription() {
52 | return description;
53 | }
54 |
55 | public PersonFullName getPatient() {
56 | return patient;
57 | }
58 |
59 | public PersonFullName getDoctor() {
60 | return doctor;
61 | }
62 |
63 | public LocalDate getCreationDate() {
64 | return creationDate;
65 | }
66 |
67 | public Long getValidity() {
68 | return validity;
69 | }
70 |
71 | public Priority getPriority() {
72 | return priority;
73 | }
74 |
75 | @Override
76 | public Long getId() {
77 | return id;
78 | }
79 |
80 | @Override
81 | public void setId(Long id) {
82 | this.id = id;
83 | }
84 | }
--------------------------------------------------------------------------------
/src/main/java/com/zufar/testtask/ui/layout/PatientVerticalLayout.java:
--------------------------------------------------------------------------------
1 | package com.zufar.testtask.ui.layout;
2 |
3 | import com.zufar.testtask.hsqldb.DaoFactory;
4 | import com.zufar.testtask.model.Patient;
5 | import com.zufar.testtask.ui.window.PatientWindow;
6 | import com.vaadin.data.util.BeanItemContainer;
7 | import com.vaadin.ui.*;
8 |
9 | import java.sql.SQLException;
10 | import java.util.List;
11 |
12 | public class PatientVerticalLayout extends AbstractVerticalLayout {
13 |
14 | public PatientVerticalLayout() {
15 | configureComponents();
16 | }
17 |
18 | private void configureComponents() {
19 | addButton.addClickListener(clickEvent -> UI.getCurrent().addWindow(new PatientWindow(this, null)));
20 | editButton.addClickListener(clickEvent -> {
21 | if (grid.getSelectedRow() == null) {
22 | disableButtons();
23 | } else {
24 | UI.getCurrent().addWindow(new PatientWindow(this, (Patient) grid.getSelectedRow()));
25 | }
26 | });
27 | label.setValue("Patient's list");
28 | disableButtons();
29 | configureGrid();
30 | refreshGrid();
31 | }
32 |
33 | private void configureGrid() {
34 | grid.setContainerDataSource(new BeanItemContainer<>(Patient.class));
35 | grid.setColumnOrder("lastName", "firstName", "patronymic", "telephoneNumber");
36 | grid.removeColumn("id");
37 | grid.addSelectionListener(selectionEvent -> {
38 | editButton.setEnabled(true);
39 | deleteButton.setEnabled(true);
40 | });
41 | }
42 |
43 | public void refreshGrid() {
44 | try {
45 | List patients = DaoFactory.getInstance().getPatientDao().getAll();
46 | grid.setContainerDataSource(new BeanItemContainer<>(Patient.class, patients));
47 | } catch (SQLException e) {
48 | Notification.show("Deleting this doctor is impossible!", "There are some problems with the database.",
49 | Notification.Type.ERROR_MESSAGE);
50 | }
51 | }
52 |
53 | void actionAfterClickDeleteButton(Button.ClickEvent event) {
54 | disableButtons();
55 | Patient selectedRow = (Patient) grid.getSelectedRow();
56 | if (selectedRow == null) {
57 | return;
58 | }
59 | try {
60 | DaoFactory.getInstance().getPatientDao().delete(selectedRow);
61 | getUI().getPrescriptionVerticalLayout().refreshGrid(null);
62 | getUI().getPrescriptionVerticalLayout().refreshPatientFilter();
63 | refreshGrid();
64 | } catch (java.sql.SQLIntegrityConstraintViolationException e) {
65 | Notification.show("Deleting this patient is impossible!", "There are some prescriptions which are connected with this patient.",
66 | Notification.Type.WARNING_MESSAGE);
67 | deleteButton.setEnabled(true);
68 | editButton.setEnabled(true);
69 | } catch (SQLException e) {
70 | Notification.show("Deleting this patient is impossible!", "There are some problems with the database.",
71 | Notification.Type.ERROR_MESSAGE);
72 | }
73 | }
74 |
75 | public void disableButtons() {
76 | deleteButton.setEnabled(false);
77 | editButton.setEnabled(false);
78 | }
79 | }
--------------------------------------------------------------------------------
/src/main/java/com/zufar/testtask/dao/AbstractCrudDao.java:
--------------------------------------------------------------------------------
1 | package com.zufar.testtask.dao;
2 |
3 | import com.zufar.testtask.model.Identified;
4 |
5 | import java.sql.Connection;
6 | import java.sql.PreparedStatement;
7 | import java.sql.ResultSet;
8 | import java.sql.SQLException;
9 | import java.util.List;
10 |
11 | public abstract class AbstractCrudDao, Id extends Long> implements CrudDao {
12 |
13 | protected Connection connection;
14 |
15 | /* Возвращает sql запрос для вставки новой записи в БД */
16 | protected abstract String getCreateQuery();
17 |
18 | /* Возвращает sql запрос для получения всех записей из БД */
19 | protected abstract String getSelectQuery();
20 |
21 | /* Возвращает sql запрос для обновления записи в БД */
22 | protected abstract String getUpdateQuery();
23 |
24 | /* Возвращает sql запрос для удаления записи из БД */
25 | protected abstract String getDeleteQuery();
26 |
27 | public AbstractCrudDao(Connection connection) {
28 | this.connection = connection;
29 | }
30 |
31 | /* Возвращает список объектов соответствующих содержимому ResultSet */
32 | protected abstract List parseResultSet(ResultSet resultSet) throws SQLException;
33 |
34 | /* Устанавливает аргументы в запрос insert в соответствии со значением полей объекта object */
35 | protected abstract void prepareStatementForInsert(PreparedStatement preparedStatement, E object) throws SQLException;
36 |
37 | /* Устанавливает аргументы в запрос update в соответствии со значением полей объекта object */
38 | protected abstract void prepareStatementForUpdate(PreparedStatement preparedStatement, E object) throws SQLException;
39 |
40 | @Override
41 | public void create(E object) throws SQLException {
42 | String createQuery = getCreateQuery();
43 | PreparedStatement statement = connection.prepareStatement(createQuery);
44 | prepareStatementForInsert(statement, object);
45 | statement.executeUpdate();
46 | }
47 |
48 | @Override
49 | public E get(Long id) throws SQLException {
50 | String selectQuery = String.format("%s WHERE id = ?", getSelectQuery());
51 | PreparedStatement statement = connection.prepareStatement(selectQuery);
52 | statement.setLong(1, id);
53 | ResultSet resultSet = statement.executeQuery();
54 | List objects = parseResultSet(resultSet);
55 | return objects.iterator().next();
56 | }
57 |
58 | @Override
59 | public void update(E object) throws SQLException {
60 | String updateQuery = getUpdateQuery();
61 | PreparedStatement preparedStatement = connection.prepareStatement(updateQuery);
62 | prepareStatementForUpdate(preparedStatement, object);
63 | preparedStatement.executeUpdate();
64 | }
65 |
66 | @Override
67 | public void delete(E object) throws SQLException {
68 | String deleteQuery = getDeleteQuery();
69 | PreparedStatement preparedStatement = connection.prepareStatement(deleteQuery);
70 | preparedStatement.setObject(1, object.getId());
71 | preparedStatement.executeUpdate();
72 | }
73 |
74 | @Override
75 | public List getAll() throws SQLException {
76 | String selectQuery = getSelectQuery();
77 | PreparedStatement preparedStatement = connection.prepareStatement(selectQuery);
78 | ResultSet resultSet = preparedStatement.executeQuery();
79 | return parseResultSet(resultSet);
80 | }
81 | }
--------------------------------------------------------------------------------
/src/main/java/com/zufar/testtask/hsqldb/PatientDao.java:
--------------------------------------------------------------------------------
1 | package com.zufar.testtask.hsqldb;
2 |
3 | import com.zufar.testtask.dao.AbstractCrudDao;
4 | import com.zufar.testtask.hsqldb.dto.PersonFullName;
5 | import com.zufar.testtask.model.Patient;
6 |
7 | import java.sql.Connection;
8 | import java.sql.PreparedStatement;
9 | import java.sql.ResultSet;
10 | import java.sql.SQLException;
11 | import java.util.ArrayList;
12 | import java.util.List;
13 |
14 | public class PatientDao extends AbstractCrudDao {
15 |
16 | PatientDao(Connection connection) {
17 | super(connection);
18 | }
19 |
20 | @Override
21 | public String getSelectQuery() {
22 | return "SELECT id, first_name, last_name, patronymic, telephone_number FROM PATIENT";
23 | }
24 |
25 | @Override
26 | public String getCreateQuery() {
27 | return "INSERT INTO PATIENT (first_name, last_name, patronymic, telephone_number) VALUES (?, ?, ?, ?)";
28 | }
29 |
30 | @Override
31 | public String getUpdateQuery() {
32 | return "UPDATE PATIENT SET first_name = ?, last_name = ?, patronymic = ?, telephone_number = ? WHERE id = ?";
33 | }
34 |
35 | @Override
36 | public String getDeleteQuery() {
37 | return "DELETE FROM PATIENT WHERE id = ?";
38 | }
39 |
40 | @Override
41 | protected List parseResultSet(ResultSet resultSet) throws SQLException {
42 | List patients = new ArrayList<>();
43 | while (resultSet.next()) {
44 | Patient patient = new Patient();
45 | patient.setId(resultSet.getLong("id"));
46 | patient.setFirstName((resultSet.getString("first_name")));
47 | patient.setLastName(resultSet.getString("last_name"));
48 | patient.setPatronymic(resultSet.getString("patronymic"));
49 | patient.setTelephoneNumber(resultSet.getLong("telephone_number"));
50 | patients.add(patient);
51 | }
52 | return patients;
53 | }
54 |
55 | @Override
56 | protected void prepareStatementForUpdate(PreparedStatement preparedStatement, Patient patient)
57 | throws SQLException, IllegalArgumentException {
58 | if (patient.getFirstName() == null || patient.getLastName() == null || patient.getPatronymic() == null ||
59 | patient.getTelephoneNumber() == null || patient.getId() == null) {
60 | throw new IllegalArgumentException("Some patient object's fields are absent!");
61 | }
62 | preparedStatement.setString(1, patient.getFirstName());
63 | preparedStatement.setString(2, patient.getLastName());
64 | preparedStatement.setString(3, patient.getPatronymic());
65 | preparedStatement.setLong(4, patient.getTelephoneNumber());
66 | preparedStatement.setLong(5, patient.getId());
67 | }
68 |
69 | @Override
70 | protected void prepareStatementForInsert(PreparedStatement preparedStatement, Patient patient)
71 | throws SQLException, IllegalArgumentException {
72 | if (patient.getFirstName() == null || patient.getLastName() == null || patient.getPatronymic() == null ||
73 | patient.getTelephoneNumber() == null) {
74 | throw new IllegalArgumentException("Some patient object's fields are absent!");
75 | }
76 | preparedStatement.setString(1, patient.getFirstName());
77 | preparedStatement.setString(2, patient.getLastName());
78 | preparedStatement.setString(3, patient.getPatronymic());
79 | preparedStatement.setLong(4, patient.getTelephoneNumber());
80 | }
81 |
82 |
83 | public List getAllFullNames() throws SQLException {
84 | PreparedStatement preparedStatement = connection.prepareStatement("SELECT id, first_name, last_name, patronymic FROM PATIENT");
85 | ResultSet resultSet = preparedStatement.executeQuery();
86 | List patientsFullNames = new ArrayList<>();
87 | while (resultSet.next()) {
88 | patientsFullNames.add(new PersonFullName(
89 | resultSet.getLong("id"),
90 | resultSet.getString("first_name"),
91 | resultSet.getString("last_name"),
92 | resultSet.getString("patronymic")
93 | ));
94 | }
95 | return patientsFullNames;
96 | }
97 | }
--------------------------------------------------------------------------------
/src/main/java/com/zufar/testtask/ui/layout/DoctorVerticalLayout.java:
--------------------------------------------------------------------------------
1 | package com.zufar.testtask.ui.layout;
2 |
3 | import com.zufar.testtask.hsqldb.DaoFactory;
4 | import com.zufar.testtask.model.Doctor;
5 | import com.zufar.testtask.ui.window.DoctorWindow;
6 | import com.vaadin.data.util.BeanItemContainer;
7 | import com.vaadin.server.FontAwesome;
8 | import com.vaadin.ui.*;
9 |
10 | import java.sql.SQLException;
11 | import java.util.List;
12 |
13 | public class DoctorVerticalLayout extends AbstractVerticalLayout {
14 |
15 | private Button statisticsButton = new Button("Statistics", this::actionAfterClickStatisticsButton);
16 |
17 | public DoctorVerticalLayout() {
18 | configureComponents();
19 | }
20 |
21 | private void configureComponents() {
22 | buttonsLayout.addComponents(statisticsButton);
23 | label.setValue("Doctor's list");
24 | statisticsButton.setIcon(FontAwesome.BAR_CHART);
25 | statisticsButton.setWidth("150");
26 | configureComponentsActionListeners();
27 | disableButtons();
28 | configureGrid();
29 | refreshGrid();
30 | }
31 |
32 | private void configureComponentsActionListeners() {
33 | addButton.addClickListener(clickEvent -> UI.getCurrent().addWindow(new DoctorWindow(this, null)));
34 | editButton.addClickListener(clickEvent -> {
35 | if (grid.getSelectedRow() == null) {
36 | disableButtons();
37 | } else {
38 | UI.getCurrent().addWindow(new DoctorWindow(this, (Doctor) grid.getSelectedRow()));
39 | }
40 | });
41 | }
42 |
43 | private void configureGrid() {
44 | grid.setContainerDataSource(new BeanItemContainer<>(Doctor.class));
45 | grid.setColumnOrder("lastName", "firstName", "patronymic", "specialization");
46 | grid.removeColumn("id");
47 | grid.addSelectionListener(selectionEvent -> {
48 | deleteButton.setEnabled(true);
49 | editButton.setEnabled(true);
50 | statisticsButton.setEnabled(true);
51 | });
52 | }
53 |
54 | public void refreshGrid() {
55 | try {
56 | List doctors = DaoFactory.getInstance().getDoctorDao().getAll();
57 | grid.setContainerDataSource(new BeanItemContainer<>(Doctor.class, doctors));
58 | } catch (SQLException e) {
59 | Notification.show("Deleting this doctor is impossible!", "There are some problems with the database.",
60 | Notification.Type.ERROR_MESSAGE);
61 | }
62 | }
63 |
64 | void actionAfterClickDeleteButton(Button.ClickEvent event) {
65 | disableButtons();
66 | Doctor selectedRow = (Doctor) grid.getSelectedRow();
67 | if (selectedRow == null) {
68 | return;
69 | }
70 | try {
71 | DaoFactory.getInstance().getDoctorDao().delete(selectedRow);
72 | getUI().getPrescriptionVerticalLayout().refreshGrid(null);
73 | refreshGrid();
74 | } catch (java.sql.SQLIntegrityConstraintViolationException e) {
75 | Notification.show("Deleting this doctor is impossible!", "There are some prescriptions which are connected with this doctor.",
76 | Notification.Type.WARNING_MESSAGE);
77 | deleteButton.setEnabled(true);
78 | editButton.setEnabled(true);
79 | statisticsButton.setEnabled(true);
80 | } catch (SQLException e) {
81 | Notification.show("Deleting this doctor is impossible!", "There are some problems with the database.",
82 | Notification.Type.ERROR_MESSAGE);
83 | }
84 | }
85 |
86 | private void actionAfterClickStatisticsButton(Button.ClickEvent event) {
87 | Doctor selectedRow = (Doctor) grid.getSelectedRow();
88 | if (selectedRow == null || selectedRow.getId() == null) {
89 | disableButtons();
90 | return;
91 | }
92 | try {
93 | Long statistics = DaoFactory.getInstance().getDoctorDao().getStatistics(selectedRow.getId());
94 | Notification.show("Note!", "This doctor made " + statistics + " prescription(s).",
95 | Notification.Type.WARNING_MESSAGE);
96 | } catch (SQLException e) {
97 | Notification.show("Deleting this doctor is impossible!", "There are some problems with the database.",
98 | Notification.Type.ERROR_MESSAGE);
99 | }
100 | }
101 |
102 | public void disableButtons() {
103 | deleteButton.setEnabled(false);
104 | editButton.setEnabled(false);
105 | statisticsButton.setEnabled(false);
106 | }
107 | }
--------------------------------------------------------------------------------
/db.script:
--------------------------------------------------------------------------------
1 | CREATE SCHEMA PUBLIC AUTHORIZATION DBA
2 | SET DATABASE DEFAULT INITIAL SCHEMA PUBLIC
3 | CREATE USER SA PASSWORD ""
4 | GRANT DBA TO SA
5 | SET SCHEMA PUBLIC
6 | CREATE MEMORY TABLE PATIENT(id BIGINT GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1) PRIMARY KEY, first_name VARCHAR(50) NOT NULL, last_name VARCHAR(50) NOT NULL, patronymic VARCHAR(50) NOT NULL,telephone_number BIGINT NOT NULL);
7 | CREATE MEMORY TABLE DOCTOR(id BIGINT GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1) PRIMARY KEY, first_name VARCHAR(50) NOT NULL, last_name VARCHAR(50) NOT NULL, patronymic VARCHAR(50) NOT NULL, specialization VARCHAR(50) NOT NULL);
8 | CREATE MEMORY TABLE PRESCRIPTION(id BIGINT GENERATED BY DEFAULT AS IDENTITY(START WITH 1, INCREMENT BY 1) PRIMARY KEY, description VARCHAR(200) NOT NULL, patient_id BIGINT NOT NULL, doctor_id BIGINT NOT NULL, creation_date DATE NOT NULL, validity BIGINT NOT NULL, priority VARCHAR(10) NOT NULL, FOREIGN KEY (patient_id) REFERENCES PATIENT(id) ON DELETE NO ACTION, FOREIGN KEY (doctor_id) REFERENCES DOCTOR(id) ON DELETE NO ACTION);
9 | SET SCHEMA PUBLIC;
10 | SET WRITE_DELAY 10;
11 | INSERT INTO PATIENT VALUES(1,'Anastasia','Vasileva','Aleksandrovna',252525);
12 | INSERT INTO PATIENT VALUES(2,'Boris','Babushkin','Georgiyevich', 242422);
13 | INSERT INTO PATIENT VALUES(3,'Viktor','Georgiyev','Iosifovich',4636456);
14 | INSERT INTO PATIENT VALUES(4,'Dmitry','Dudinsky','Innokentyevich',5464564);
15 | INSERT INTO PATIENT VALUES(5,'Yelena','Yeremeyeva','Karpovna',5464564);
16 | INSERT INTO PATIENT VALUES(6,'Pyotr','Vorobyov','Lvovich',5464564);
17 | INSERT INTO PATIENT VALUES(7,'Ella','Runieva','Aleksandrova',252525);
18 | INSERT INTO PATIENT VALUES(8,'Boris','Malyshev','Nikolayevich', 242422);
19 | INSERT INTO PATIENT VALUES(9,'Viktor','Smelyansky','Maratovich',4636456);
20 | INSERT INTO PATIENT VALUES(10,'Dmitry','Tatishchev','Olegovich',5464564);
21 | INSERT INTO PATIENT VALUES(11,'Yelena','Frolova','Kirillovna',5464564);
22 | INSERT INTO PATIENT VALUES(12,'Pyotr','Tikhonov','Lvovich',5464564);
23 | INSERT INTO DOCTOR VALUES (1,'Zhanna','Strizheva','Maratovna','Surgeon');
24 | INSERT INTO DOCTOR VALUES (2,'Zoya','Udalova','Maksimovna', 'Dentist');
25 | INSERT INTO DOCTOR VALUES (3,'Irina','Vafina','Kirillovna','Therapist');
26 | INSERT INTO DOCTOR VALUES (4,'Andrey','Malyshev','Ilyich','Dentist');
27 | INSERT INTO DOCTOR VALUES (5,'Ksenia','Akopyan','Leontyevna','Neurologist');
28 | INSERT INTO DOCTOR VALUES (6,'Leonid','Kovalsky','Glebovich','Therapist');
29 | INSERT INTO DOCTOR VALUES (7,'Leonid ','Vorobyov','Ibragimovich','Neurologist');
30 | INSERT INTO DOCTOR VALUES (8,'Maria','Lushina','Karpovna', 'Dentist');
31 | INSERT INTO DOCTOR VALUES (9,'Ruslan','Nuriyev','Antonovich','Therapist');
32 | INSERT INTO DOCTOR VALUES (10,'Pavel','Lapshin','Georgiyevich','Dermatologist');
33 | INSERT INTO DOCTOR VALUES (11,'Oleg','Stroyev','Losifovich','Dermatologist');
34 | INSERT INTO DOCTOR VALUES (12,'Natalia','Anichkina','Innokentyevna','Therapist');
35 | INSERT INTO PRESCRIPTION VALUES (1,'You should more sleep.',8,1,'2012-08-07', 100,'STATIM');
36 | INSERT INTO PRESCRIPTION VALUES (2,'You should more relax.',9,1,'2001-07-10',150,'NORMAL');
37 | INSERT INTO PRESCRIPTION VALUES (3,'You should more run.',3,1,'2008-08-01',300,'SITO');
38 | INSERT INTO PRESCRIPTION VALUES (4,'You should more smile.',4,1,'2015-08-07',500, 'STATIM');
39 | INSERT INTO PRESCRIPTION VALUES (5,'You should more relax.',5,2,'2012-08-07', 100,'NORMAL');
40 | INSERT INTO PRESCRIPTION VALUES (6,'You should more eat.',6,2,'2001-07-10',150,'NORMAL');
41 | INSERT INTO PRESCRIPTION VALUES (7,'You should more run.',7,2,'2008-08-01',300,'SITO');
42 | INSERT INTO PRESCRIPTION VALUES (8,'You should more sleep.',8,3,'2015-08-07',500, 'NORMAL');
43 | INSERT INTO PRESCRIPTION VALUES (9,'You should more smile.',9,4,'2012-08-07', 100,'NORMAL');
44 | INSERT INTO PRESCRIPTION VALUES (10,'You should more drink.',10,4,'2001-07-10',150,'STATIM');
45 | INSERT INTO PRESCRIPTION VALUES (11,'You should more eat.',11,5,'2008-08-01',300,'NORMAL');
46 | INSERT INTO PRESCRIPTION VALUES (12,'You should more sleep.',12,6,'2015-08-07',500, 'SITO');
47 | INSERT INTO PRESCRIPTION VALUES (13,'You should more drink.',1,7,'2012-08-07', 100,'NORMAL');
48 | INSERT INTO PRESCRIPTION VALUES (14,'You should more run.',2,7,'2001-07-10',150,'NORMAL');
49 | INSERT INTO PRESCRIPTION VALUES (15,'You should more relax.',7,7,'2008-08-01',300,'STATIM');
50 | INSERT INTO PRESCRIPTION VALUES (16,'You should more sleep.',5,8,'2015-08-07',500, 'NORMAL');
51 | INSERT INTO PRESCRIPTION VALUES (17,'You should more relax.',6,8,'2012-08-07', 100,'SITO');
52 | INSERT INTO PRESCRIPTION VALUES (18,'You should more sleep.',2,1,'2001-07-10',150,'STATIM');
53 | INSERT INTO PRESCRIPTION VALUES (19,'You should more smile.',3,4,'2008-08-01',300,'NORMAL');
54 | INSERT INTO PRESCRIPTION VALUES (20,'You should more run.',4,3,'2015-08-07',500, 'NORMAL');
--------------------------------------------------------------------------------
/src/main/java/com/zufar/testtask/hsqldb/DoctorDao.java:
--------------------------------------------------------------------------------
1 | package com.zufar.testtask.hsqldb;
2 |
3 | import com.zufar.testtask.dao.AbstractCrudDao;
4 | import com.zufar.testtask.hsqldb.dto.PersonFullName;
5 | import com.zufar.testtask.model.Doctor;
6 |
7 | import java.sql.Connection;
8 | import java.sql.PreparedStatement;
9 | import java.sql.ResultSet;
10 | import java.sql.SQLException;
11 | import java.util.ArrayList;
12 | import java.util.List;
13 |
14 | public class DoctorDao extends AbstractCrudDao {
15 |
16 | DoctorDao(Connection connection) {
17 | super(connection);
18 | }
19 |
20 | @Override
21 | public String getSelectQuery() {
22 | return "SELECT id, first_name, last_name, patronymic, specialization FROM DOCTOR";
23 | }
24 |
25 | @Override
26 | public String getCreateQuery() {
27 | return "INSERT INTO DOCTOR (first_name, last_name, patronymic, specialization) VALUES (?, ?, ?, ?)";
28 | }
29 |
30 | @Override
31 | public String getUpdateQuery() {
32 | return "UPDATE DOCTOR SET first_name = ?, last_name = ?, patronymic = ?, specialization = ? WHERE id = ?";
33 | }
34 |
35 | @Override
36 | public String getDeleteQuery() {
37 | return "DELETE FROM DOCTOR WHERE id= ?";
38 | }
39 |
40 | @Override
41 | protected List parseResultSet(ResultSet resultSet) throws SQLException {
42 | List doctors = new ArrayList<>();
43 | while (resultSet.next()) {
44 | Doctor doctor = new Doctor();
45 | doctor.setId(resultSet.getLong("id"));
46 | doctor.setFirstName((resultSet.getString("first_name")));
47 | doctor.setLastName(resultSet.getString("last_name"));
48 | doctor.setPatronymic(resultSet.getString("patronymic"));
49 | doctor.setSpecialization(resultSet.getString("specialization"));
50 | doctors.add(doctor);
51 | }
52 | return doctors;
53 | }
54 |
55 | @Override
56 | protected void prepareStatementForUpdate(PreparedStatement preparedStatement, Doctor doctor)
57 | throws SQLException, IllegalArgumentException {
58 | if (doctor.getFirstName() == null || doctor.getLastName() == null || doctor.getPatronymic() == null ||
59 | doctor.getSpecialization() == null || doctor.getId() == null) {
60 | throw new IllegalArgumentException("Some doctor object's fields are absent!");
61 | }
62 | preparedStatement.setString(1, doctor.getFirstName());
63 | preparedStatement.setString(2, doctor.getLastName());
64 | preparedStatement.setString(3, doctor.getPatronymic());
65 | preparedStatement.setString(4, doctor.getSpecialization());
66 | preparedStatement.setLong(5, doctor.getId());
67 | }
68 |
69 | @Override
70 | protected void prepareStatementForInsert(PreparedStatement preparedStatement, Doctor doctor)
71 | throws SQLException, IllegalArgumentException {
72 | if (doctor.getFirstName() == null || doctor.getLastName() == null || doctor.getPatronymic() == null ||
73 | doctor.getSpecialization() == null) {
74 | throw new IllegalArgumentException("Some doctor object's fields are absent!");
75 | }
76 | preparedStatement.setString(1, doctor.getFirstName());
77 | preparedStatement.setString(2, doctor.getLastName());
78 | preparedStatement.setString(3, doctor.getPatronymic());
79 | preparedStatement.setString(4, doctor.getSpecialization());
80 | }
81 |
82 | public List getAllFullNames() throws SQLException {
83 | PreparedStatement preparedStatement = connection.prepareStatement("SELECT id, first_name, last_name, patronymic FROM DOCTOR");
84 | ResultSet resultSet = preparedStatement.executeQuery();
85 | List doctorsFullNames = new ArrayList<>();
86 | while (resultSet.next()) {
87 | doctorsFullNames.add(new PersonFullName(
88 | resultSet.getLong("id"),
89 | resultSet.getString("first_name"),
90 | resultSet.getString("last_name"),
91 | resultSet.getString("patronymic")
92 | ));
93 | }
94 | return doctorsFullNames;
95 | }
96 |
97 | public Long getStatistics(Long primaryKey) throws SQLException {
98 | PreparedStatement preparedStatement = connection.prepareStatement(
99 | "SELECT COUNT(id) AS prescription_count FROM PRESCRIPTION WHERE doctor_id = ?");
100 | preparedStatement.setLong(1, primaryKey);
101 | ResultSet resultSet = preparedStatement.executeQuery();
102 | if (resultSet.next()) {
103 | return resultSet.getLong("prescription_count");
104 | }
105 | throw new SQLException();
106 | }
107 | }
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 | com.zufar
6 | Hospital-Prescription
7 | war
8 | 1.0
9 | Test Task
10 |
11 |
12 |
13 | Zufar Sunagatov
14 | zuf999@mail.com
15 |
16 | architect
17 | developer
18 |
19 |
20 |
21 |
22 |
23 | UTF-8
24 | 7.6.7
25 |
26 |
27 |
28 |
29 | vaadin-addons
30 | http://maven.vaadin.com/vaadin-addons
31 |
32 |
33 | vaadin-snapshots
34 | http://oss.sonatype.org/content/repositories/vaadin-snapshots/
35 |
36 | false
37 |
38 |
39 | true
40 |
41 |
42 |
43 |
44 |
45 | vaadin-snapshots
46 | http://oss.sonatype.org/content/repositories/vaadin-snapshots/
47 |
48 | false
49 |
50 |
51 | true
52 |
53 |
54 |
55 |
56 |
57 | com.vaadin
58 | vaadin-server
59 | ${vaadin.version}
60 |
61 |
62 | com.vaadin
63 | vaadin-client-compiled
64 | ${vaadin.version}
65 |
66 |
67 | com.vaadin
68 | vaadin-themes
69 | ${vaadin.version}
70 |
71 |
72 | javax.servlet
73 | servlet-api
74 | 2.4
75 | provided
76 |
77 |
78 | org.hsqldb
79 | hsqldb
80 | 2.3.4
81 |
82 |
83 |
84 |
85 | src/main/java
86 | src/test/java
87 |
88 |
89 | org.apache.maven.plugins
90 | maven-compiler-plugin
91 | 3.5.1
92 |
93 | 1.8
94 | 1.8
95 |
96 |
97 |
98 | org.apache.maven.plugins
99 | maven-dependency-plugin
100 |
101 | ${project.build.directory}/lib/
102 | false
103 | false
104 | true
105 |
106 | junit
107 |
108 |
109 |
110 | copy-dependencies
111 | package
112 |
113 | copy-dependencies
114 |
115 |
116 |
117 |
118 |
119 | org.mortbay.jetty
120 | jetty-maven-plugin
121 | 8.1.16.v20140903
122 |
123 |
124 |
125 |
--------------------------------------------------------------------------------
/src/main/java/com/zufar/testtask/ui/window/DoctorWindow.java:
--------------------------------------------------------------------------------
1 | package com.zufar.testtask.ui.window;
2 |
3 | import com.zufar.testtask.ui.layout.DoctorVerticalLayout;
4 | import com.vaadin.data.validator.StringLengthValidator;
5 | import com.vaadin.data.validator.RegexpValidator;
6 | import com.zufar.testtask.hsqldb.DaoFactory;
7 | import com.zufar.testtask.hsqldb.DoctorDao;
8 | import com.zufar.testtask.model.Doctor;
9 | import com.vaadin.event.FieldEvents;
10 | import com.vaadin.data.Validator;
11 |
12 | import java.sql.SQLException;
13 |
14 | import com.vaadin.ui.*;
15 |
16 | public class DoctorWindow extends AbstractWindow {
17 |
18 | private TextField firstName = new TextField("First name:");
19 | private TextField lastName = new TextField("Last name:");
20 | private TextField patronymic = new TextField("Patronymic:");
21 | private TextField specialization = new TextField("Specialization:");
22 | private DoctorVerticalLayout doctorVerticalLayout;
23 | private Doctor selectedDoctor;
24 |
25 | public DoctorWindow(DoctorVerticalLayout doctorVerticalLayout, Doctor selectedDoctor) {
26 | this.doctorVerticalLayout = doctorVerticalLayout;
27 | this.selectedDoctor = selectedDoctor;
28 | this.verticalFields.addComponents(lastName, firstName, patronymic, specialization);
29 | configureComponents();
30 | }
31 |
32 | private void configureComponents() {
33 | firstName.focus();
34 | configureComponentsValidator();
35 | configureComponentsWidth();
36 | configureComponentsValidators();
37 | configureComponentsValidationVisibility();
38 | configureComponentsRequired();
39 | configureComponentsTextChangeEventMode();
40 | configureComponentsChangeListeners();
41 | configureComponentsMaxLength();
42 | configureComponentsImmediate();
43 | configureComponentsValue();
44 | }
45 |
46 | private void configureComponentsValidator() {
47 | RegexpValidator wordValidator = new RegexpValidator("[A-Z][a-z]{1,50}",true,
48 | "Enter the word length from 2 to 50 characters (with a capital letter)");
49 | firstName.addValidator(wordValidator);
50 | lastName.addValidator(wordValidator);
51 | patronymic.addValidator(wordValidator);
52 | specialization.addValidator(wordValidator);
53 | }
54 |
55 | private void configureComponentsValue() {
56 | if (selectedDoctor == null) {
57 | return;
58 | }
59 | firstName.setValue(selectedDoctor.getFirstName());
60 | lastName.setValue(selectedDoctor.getLastName());
61 | patronymic.setValue(selectedDoctor.getPatronymic());
62 | specialization.setValue(selectedDoctor.getSpecialization());
63 | }
64 |
65 | private void configureComponentsImmediate() {
66 | firstName.setImmediate(true);
67 | lastName.setImmediate(true);
68 | patronymic.setImmediate(true);
69 | specialization.setImmediate(true);
70 | }
71 |
72 | private void configureComponentsChangeListeners() {
73 | firstName.addTextChangeListener(event -> actionAfterTextChangeEvent(event, firstName));
74 | lastName.addTextChangeListener(event -> actionAfterTextChangeEvent(event, lastName));
75 | patronymic.addTextChangeListener(event -> actionAfterTextChangeEvent(event, patronymic));
76 | specialization.addTextChangeListener(event -> actionAfterTextChangeEvent(event, specialization));
77 | }
78 |
79 | private void configureComponentsRequired() {
80 | firstName.setRequired(true);
81 | lastName.setRequired(true);
82 | patronymic.setRequired(true);
83 | specialization.setRequired(true);
84 | }
85 |
86 | private void configureComponentsTextChangeEventMode() {
87 | firstName.setTextChangeEventMode(AbstractTextField.TextChangeEventMode.EAGER);
88 | lastName.setTextChangeEventMode(AbstractTextField.TextChangeEventMode.EAGER);
89 | patronymic.setTextChangeEventMode(AbstractTextField.TextChangeEventMode.EAGER);
90 | specialization.setTextChangeEventMode(AbstractTextField.TextChangeEventMode.EAGER);
91 | }
92 |
93 | private void configureComponentsValidationVisibility() {
94 | firstName.setValidationVisible(true);
95 | lastName.setValidationVisible(true);
96 | patronymic.setValidationVisible(true);
97 | specialization.setValidationVisible(true);
98 | }
99 |
100 | private void configureComponentsValidators() {
101 | StringLengthValidator stringLengthValidator =
102 | new StringLengthValidator("Prompt is empty", 1, 50, false);
103 | firstName.addValidator(stringLengthValidator);
104 | lastName.addValidator(stringLengthValidator);
105 | patronymic.addValidator(stringLengthValidator);
106 | specialization.addValidator(stringLengthValidator);
107 | }
108 |
109 | private void configureComponentsMaxLength() {
110 | firstName.setMaxLength(50);
111 | lastName.setMaxLength(50);
112 | patronymic.setMaxLength(50);
113 | specialization.setMaxLength(50);
114 | }
115 |
116 | private void configureComponentsWidth() {
117 | firstName.setWidth(String.valueOf(300));
118 | lastName.setWidth(String.valueOf(300));
119 | patronymic.setWidth(String.valueOf(300));
120 | specialization.setWidth(String.valueOf(300));
121 | }
122 |
123 | void actionAfterClickOkButton(Button.ClickEvent clickEvent) {
124 | doctorVerticalLayout.disableButtons();
125 | Doctor doctor = new Doctor(firstName.getValue(), lastName.getValue(), patronymic.getValue(), specialization.getValue());
126 | try {
127 | DoctorDao doctorDao = DaoFactory.getInstance().getDoctorDao();
128 | if (selectedDoctor == null) {
129 | doctorDao.create(doctor);
130 | } else {
131 | if (selectedDoctor.getId() == null) {
132 | throw new IllegalArgumentException();
133 | }
134 | doctor.setId(selectedDoctor.getId());
135 | doctorDao.update(doctor);
136 | }
137 | getUI().getPrescriptionVerticalLayout().refreshGrid(null);
138 | doctorVerticalLayout.refreshGrid();
139 | close();
140 | } catch (SQLException e) {
141 | Notification.show("Taking action for this doctor is impossible!", "There are some problems with the database.",
142 | Notification.Type.ERROR_MESSAGE);
143 | }
144 | }
145 |
146 | private void actionAfterTextChangeEvent(FieldEvents.TextChangeEvent event, TextField textField) {
147 | textField.setValue(event.getText());
148 | textField.setCursorPosition(event.getCursorPosition());
149 | try {
150 | firstName.validate();
151 | lastName.validate();
152 | patronymic.validate();
153 | specialization.validate();
154 | okButton.setEnabled(true);
155 | } catch (Validator.InvalidValueException e) {
156 | okButton.setEnabled(false);
157 | }
158 | }
159 | }
--------------------------------------------------------------------------------
/src/main/java/com/zufar/testtask/ui/window/PatientWindow.java:
--------------------------------------------------------------------------------
1 | package com.zufar.testtask.ui.window;
2 |
3 | import com.zufar.testtask.hsqldb.PatientDao;
4 | import com.vaadin.data.validator.RegexpValidator;
5 | import com.zufar.testtask.hsqldb.DaoFactory;
6 | import com.zufar.testtask.model.Patient;
7 | import com.zufar.testtask.ui.layout.PatientVerticalLayout;
8 | import com.vaadin.data.Validator;
9 | import com.vaadin.data.util.converter.StringToLongConverter;
10 | import com.vaadin.data.validator.LongRangeValidator;
11 | import com.vaadin.data.validator.StringLengthValidator;
12 | import com.vaadin.event.FieldEvents;
13 | import com.vaadin.ui.*;
14 |
15 | import java.sql.SQLException;
16 |
17 | public class PatientWindow extends AbstractWindow {
18 |
19 | private TextField firstName = new TextField("First name:");
20 | private TextField lastName = new TextField("Last name:");
21 | private TextField patronymic = new TextField("Patronymic:");
22 | private TextField telephoneNumber = new TextField("Telephone number:");
23 | private PatientVerticalLayout patientVerticalLayout;
24 | private Patient selectedPatient;
25 |
26 | public PatientWindow(PatientVerticalLayout doctorVerticalLayout, Patient selectedPatient) {
27 | this.patientVerticalLayout = doctorVerticalLayout;
28 | this.selectedPatient = selectedPatient;
29 | this.verticalFields.addComponents(lastName, firstName, patronymic, telephoneNumber);
30 | configureComponents();
31 | }
32 |
33 | private void configureComponents() {
34 | firstName.focus();
35 | telephoneNumber.setConverter(new StringToLongConverter());
36 | telephoneNumber.setNullRepresentation("");
37 | configureComponentsValidator();
38 | configureComponentsWidth();
39 | configureComponentsValidators();
40 | configureComponentsValidationVisibility();
41 | configureComponentsRequired();
42 | configureComponentsTextChangeEventMode();
43 | configureComponentsChangeListeners();
44 | configureComponentsMaxLength();
45 | configureComponentsImmediate();
46 | configureComponentsValue();
47 | }
48 |
49 | private void configureComponentsValue() {
50 | if (selectedPatient == null) {
51 | return;
52 | }
53 | firstName.setValue(selectedPatient.getFirstName());
54 | lastName.setValue(selectedPatient.getLastName());
55 | patronymic.setValue(selectedPatient.getPatronymic());
56 | telephoneNumber.setValue(String.valueOf(selectedPatient.getTelephoneNumber()));
57 | }
58 |
59 | private void configureComponentsValidator() {
60 | RegexpValidator wordValidator = new RegexpValidator("[A-Z][a-z]{1,50}", true,
61 | "Enter the word length from 3 to 50 characters (with a capital letter)");
62 | firstName.addValidator(wordValidator);
63 | lastName.addValidator(wordValidator);
64 | patronymic.addValidator(wordValidator);
65 | telephoneNumber.addValidator(new LongRangeValidator("Value is negative", 0L, Long.MAX_VALUE));
66 | }
67 |
68 | private void configureComponentsImmediate() {
69 | firstName.setImmediate(true);
70 | lastName.setImmediate(true);
71 | patronymic.setImmediate(true);
72 | telephoneNumber.setImmediate(true);
73 | }
74 |
75 | private void configureComponentsMaxLength() {
76 | firstName.setMaxLength(50);
77 | lastName.setMaxLength(50);
78 | patronymic.setMaxLength(50);
79 | telephoneNumber.setMaxLength(18);
80 | }
81 |
82 | private void configureComponentsChangeListeners() {
83 | firstName.addTextChangeListener(event -> actionAfterTextChangeEvent(event, firstName));
84 | lastName.addTextChangeListener(event -> actionAfterTextChangeEvent(event, lastName));
85 | patronymic.addTextChangeListener(event -> actionAfterTextChangeEvent(event, patronymic));
86 | telephoneNumber.addTextChangeListener(event -> actionAfterTextChangeEvent(event, telephoneNumber));
87 | }
88 |
89 | private void configureComponentsTextChangeEventMode() {
90 | firstName.setTextChangeEventMode(AbstractTextField.TextChangeEventMode.EAGER);
91 | lastName.setTextChangeEventMode(AbstractTextField.TextChangeEventMode.EAGER);
92 | patronymic.setTextChangeEventMode(AbstractTextField.TextChangeEventMode.EAGER);
93 | telephoneNumber.setTextChangeEventMode(AbstractTextField.TextChangeEventMode.EAGER);
94 | }
95 |
96 | private void configureComponentsRequired() {
97 | firstName.setRequired(true);
98 | lastName.setRequired(true);
99 | patronymic.setRequired(true);
100 | telephoneNumber.setRequired(true);
101 | }
102 |
103 | private void configureComponentsValidationVisibility() {
104 | firstName.setValidationVisible(true);
105 | lastName.setValidationVisible(true);
106 | patronymic.setValidationVisible(true);
107 | telephoneNumber.setValidationVisible(true);
108 | }
109 |
110 | private void configureComponentsValidators() {
111 | StringLengthValidator stringLengthValidator =
112 | new StringLengthValidator("Prompt is empty", 1, 50, false);
113 | telephoneNumber.addValidator(new LongRangeValidator("Value is negative", 0L, Long.MAX_VALUE));
114 | firstName.addValidator(stringLengthValidator);
115 | lastName.addValidator(stringLengthValidator);
116 | patronymic.addValidator(stringLengthValidator);
117 | }
118 |
119 | private void configureComponentsWidth() {
120 | firstName.setWidth(String.valueOf(300));
121 | lastName.setWidth(String.valueOf(300));
122 | patronymic.setWidth(String.valueOf(300));
123 | telephoneNumber.setWidth(String.valueOf(300));
124 | }
125 |
126 | void actionAfterClickOkButton(Button.ClickEvent clickEvent) {
127 | patientVerticalLayout.disableButtons();
128 | Patient patient = new Patient(firstName.getValue(), lastName.getValue(), patronymic.getValue(),
129 | Long.parseLong(telephoneNumber.getConvertedValue().toString()));
130 | try {
131 | PatientDao patientDao = DaoFactory.getInstance().getPatientDao();
132 | if (selectedPatient == null) {
133 | patientDao.create(patient);
134 | } else {
135 | if (selectedPatient.getId() == null) {
136 | throw new IllegalArgumentException();
137 | }
138 | patient.setId(selectedPatient.getId());
139 | patientDao.update(patient);
140 | }
141 | getUI().getPrescriptionVerticalLayout().refreshGrid(null);
142 | getUI().getPrescriptionVerticalLayout().refreshPatientFilter();
143 | patientVerticalLayout.refreshGrid();
144 | close();
145 | } catch (SQLException e) {
146 | Notification.show("Taking action for this patient is impossible!", "There are some problems with the database.",
147 | Notification.Type.ERROR_MESSAGE);
148 | }
149 | }
150 |
151 | private void actionAfterTextChangeEvent(FieldEvents.TextChangeEvent event, TextField textField) {
152 | textField.setValue(event.getText());
153 | textField.setCursorPosition(event.getCursorPosition());
154 | try {
155 | firstName.validate();
156 | lastName.validate();
157 | patronymic.validate();
158 | telephoneNumber.validate();
159 | okButton.setEnabled(true);
160 | } catch (Validator.InvalidValueException e) {
161 | okButton.setEnabled(false);
162 | }
163 | }
164 | }
--------------------------------------------------------------------------------
/src/main/java/com/zufar/testtask/ui/layout/PrescriptionVerticalLayout.java:
--------------------------------------------------------------------------------
1 | package com.zufar.testtask.ui.layout;
2 |
3 | import com.zufar.testtask.hsqldb.dto.PersonFullName;
4 | import com.zufar.testtask.model.Prescription;
5 | import com.zufar.testtask.hsqldb.DaoFactory;
6 | import com.zufar.testtask.model.Priority;
7 | import com.zufar.testtask.ui.window.PrescriptionWindow;
8 | import com.vaadin.data.Property;
9 | import com.vaadin.data.util.BeanItemContainer;
10 | import com.vaadin.event.FieldEvents;
11 | import com.vaadin.server.FontAwesome;
12 | import com.vaadin.ui.*;
13 |
14 | import java.sql.SQLException;
15 | import java.util.List;
16 |
17 | public class PrescriptionVerticalLayout extends AbstractVerticalLayout {
18 |
19 | private TextField descriptionFilter = new TextField("Description:");
20 | private NativeSelect patientFilter = new NativeSelect("Patient:");
21 | private NativeSelect priorityFilter = new NativeSelect("Priority:");
22 | private Button filterButton = new Button("Apply", clickEvent -> {
23 | try {
24 | List prescriptions = DaoFactory.getInstance().getPrescriptionDao().getAllByFilters(
25 | descriptionFilter.getValue(), (PersonFullName) patientFilter.getValue(), (Priority) priorityFilter.getValue());
26 | refreshGrid(prescriptions);
27 | } catch (SQLException e) {
28 | Notification.show("Filtering is impossible!", "There are some problems with the database.",
29 | Notification.Type.ERROR_MESSAGE);
30 | }
31 | });
32 |
33 | public PrescriptionVerticalLayout() {
34 | configureComponents();
35 | }
36 |
37 | private void configureComponents() {
38 | buildLayout();
39 | addButton.addClickListener(clickEvent -> UI.getCurrent().addWindow(new PrescriptionWindow(this, null)));
40 | editButton.addClickListener(clickEvent -> {
41 | if (grid.getSelectedRow() == null) {
42 | disableButtons();
43 | } else {
44 | UI.getCurrent().addWindow(new PrescriptionWindow(this, (Prescription) grid.getSelectedRow()));
45 | }
46 | });
47 | label.setValue("Prescription's list");
48 | filterButton.setEnabled(false);
49 | filterButton.setIcon(FontAwesome.CHECK);
50 | configureFilterComponents();
51 | disableButtons();
52 | configureGrid();
53 | refreshGrid(null);
54 | }
55 |
56 | private void buildLayout() {
57 | HorizontalLayout filterLayout = new HorizontalLayout(descriptionFilter, patientFilter, priorityFilter, filterButton);
58 | filterLayout.setMargin(true);
59 | filterLayout.setSpacing(true);
60 | filterLayout.setComponentAlignment(filterButton, Alignment.BOTTOM_RIGHT);
61 | Panel filterPanel = new Panel("Prescription's filter panel");
62 | filterPanel.setContent(filterLayout);
63 | addComponents(label, filterPanel, grid, buttonsLayout);
64 | }
65 |
66 | private void configureFilterComponents() {
67 | descriptionFilter.setTextChangeEventMode(AbstractTextField.TextChangeEventMode.EAGER);
68 | priorityFilter.addItems(Priority.NORMAL, Priority.SITO, Priority.STATIM);
69 | descriptionFilter.setInputPrompt("description");
70 | priorityFilter.setValue(null);
71 | configureFilterComponentsImmediate();
72 | configureFilterComponentsNullSelectionAllowed();
73 | configureFilterComponentsActionListeners();
74 | configureFilterComponentsNullSelectionItemIds();
75 | configureFilterComponentsWidth();
76 | configureFilterComponentsHeight();
77 | refreshPatientFilter();
78 | }
79 |
80 | private void configureFilterComponentsNullSelectionItemIds() {
81 | patientFilter.setNullSelectionItemId("");
82 | priorityFilter.setNullSelectionItemId("");
83 | }
84 |
85 | private void configureFilterComponentsActionListeners() {
86 | patientFilter.addValueChangeListener(event -> actionAfterSelectChangeEvent(event, patientFilter));
87 | priorityFilter.addValueChangeListener(event -> actionAfterSelectChangeEvent(event, priorityFilter));
88 | patientFilter.addContextClickListener(contextClickEvent -> refreshPatientFilter());
89 | descriptionFilter.addTextChangeListener(event -> actionAfterTextChangeEvent(event, descriptionFilter));
90 | }
91 |
92 | private void configureFilterComponentsNullSelectionAllowed() {
93 | patientFilter.setNullSelectionAllowed(true);
94 | priorityFilter.setNullSelectionAllowed(true);
95 | }
96 |
97 | private void configureFilterComponentsImmediate() {
98 | descriptionFilter.setImmediate(true);
99 | patientFilter.setImmediate(true);
100 | }
101 |
102 | private void configureFilterComponentsHeight() {
103 | descriptionFilter.setHeight("30");
104 | patientFilter.setHeight("30");
105 | priorityFilter.setHeight("30");
106 | filterButton.setHeight("30");
107 | }
108 |
109 | private void configureFilterComponentsWidth() {
110 | filterButton.setWidth("150");
111 | descriptionFilter.setWidth("200");
112 | patientFilter.setWidth("200");
113 | priorityFilter.setWidth("200");
114 | }
115 |
116 | private void configureGrid() {
117 | grid.setContainerDataSource(new BeanItemContainer<>(Prescription.class));
118 | grid.setColumnOrder("description", "patient", "doctor", "creationDate", "validity", "priority");
119 | grid.removeColumn("id");
120 | grid.addSelectionListener(selectionEvent -> {
121 | deleteButton.setEnabled(true);
122 | editButton.setEnabled(true);
123 | });
124 | }
125 |
126 | private void actionAfterTextChangeEvent(FieldEvents.TextChangeEvent event, TextField textField) {
127 | textField.setValue(event.getText());
128 | textField.setCursorPosition(event.getCursorPosition());
129 | if (patientFilter.isEmpty() && descriptionFilter.isEmpty() && priorityFilter.isEmpty()) {
130 | refreshGrid(null);
131 | filterButton.setEnabled(false);
132 | } else {
133 | filterButton.setEnabled(true);
134 | }
135 | }
136 |
137 | private void actionAfterSelectChangeEvent(Property.ValueChangeEvent event, NativeSelect select) {
138 | select.setValue(event.getProperty().getValue());
139 | if (patientFilter.isEmpty() && descriptionFilter.isEmpty() && priorityFilter.isEmpty()) {
140 | refreshGrid(null);
141 | filterButton.setEnabled(false);
142 | } else {
143 | filterButton.setEnabled(true);
144 | }
145 | }
146 |
147 | public void refreshGrid(List filteredPrescriptions) {
148 | if (filteredPrescriptions != null) {
149 | grid.setContainerDataSource(new BeanItemContainer<>(Prescription.class, filteredPrescriptions));
150 | return;
151 | }
152 | try {
153 | List prescriptions = DaoFactory.getInstance().getPrescriptionDao().getAll();
154 | grid.setContainerDataSource(new BeanItemContainer<>(Prescription.class, prescriptions));
155 | grid.setColumnOrder("description", "patient", "doctor", "creationDate", "validity", "priority");
156 | } catch (SQLException e) {
157 | Notification.show("Refreshing the grid is impossible!", "There are some problems with the database.",
158 | Notification.Type.ERROR_MESSAGE);
159 | }
160 | }
161 |
162 | public void disableButtons() {
163 | deleteButton.setEnabled(false);
164 | editButton.setEnabled(false);
165 | }
166 |
167 | public boolean refreshPatientFilter() {
168 | try {
169 | patientFilter.removeAllItems();
170 | patientFilter.setValue(null);
171 | List patientsFullNames = DaoFactory.getInstance().getPatientDao().getAllFullNames();
172 | patientFilter.addItems(patientsFullNames);
173 | } catch (SQLException e) {
174 | return true;
175 | }
176 | return false;
177 | }
178 |
179 | @Override
180 | void actionAfterClickDeleteButton(Button.ClickEvent event) {
181 | disableButtons();
182 | if (grid.getSelectedRow() == null) {
183 | return;
184 | }
185 | try {
186 | DaoFactory.getInstance().getPrescriptionDao().delete((Prescription) grid.getSelectedRow());
187 | refreshGrid(null);
188 | } catch (SQLException e) {
189 | Notification.show("Deleting this prescription is impossible!", "There are some problems with the database.",
190 | Notification.Type.ERROR_MESSAGE);
191 | }
192 | }
193 | }
--------------------------------------------------------------------------------
/src/main/java/com/zufar/testtask/hsqldb/PrescriptionDao.java:
--------------------------------------------------------------------------------
1 | package com.zufar.testtask.hsqldb;
2 |
3 | import com.zufar.testtask.dao.AbstractCrudDao;
4 | import com.zufar.testtask.hsqldb.dto.PersonFullName;
5 | import com.zufar.testtask.model.Prescription;
6 | import com.zufar.testtask.model.Priority;
7 |
8 | import java.sql.*;
9 | import java.sql.Date;
10 | import java.time.LocalDate;
11 | import java.time.format.DateTimeFormatter;
12 | import java.util.*;
13 |
14 | public class PrescriptionDao extends AbstractCrudDao {
15 |
16 | PrescriptionDao(Connection connection) {
17 | super(connection);
18 | }
19 |
20 | @Override
21 | public String getSelectQuery() {
22 | return " SELECT \n" +
23 | " PRESCRIPTION.id AS id, PRESCRIPTION.description AS description, PRESCRIPTION.creation_date AS creation_date, \n" +
24 | " PRESCRIPTION.validity AS validity, PRESCRIPTION.priority AS priority, PATIENT.id AS patientID,\n" +
25 | " PATIENT.first_name AS patientFirstName, PATIENT.last_name AS patientLastName, PATIENT.patronymic AS patientPatronymic,\n" +
26 | " DOCTOR.id AS doctorID, DOCTOR.first_name AS doctorFirstName, DOCTOR.last_name AS doctorLastName,\n" +
27 | " DOCTOR.patronymic AS doctorPatronymic FROM PRESCRIPTION JOIN PATIENT ON PRESCRIPTION.patient_id = PATIENT.id \n" +
28 | " JOIN DOCTOR ON PRESCRIPTION.doctor_id = DOCTOR.id";
29 | }
30 |
31 | @Override
32 | public String getCreateQuery() {
33 | return "INSERT INTO PRESCRIPTION " +
34 | "(description, patient_id, doctor_id, creation_date, validity, priority) VALUES (?, ?, ?, ?, ?, ?)";
35 | }
36 |
37 | @Override
38 | public String getUpdateQuery() {
39 | return "UPDATE PRESCRIPTION SET description = ?, patient_id = ?, doctor_id = ?, creation_date = ?," +
40 | " validity = ?, priority = ? WHERE id = ?";
41 | }
42 |
43 | @Override
44 | public String getDeleteQuery() {
45 | return "DELETE FROM PRESCRIPTION WHERE id= ?";
46 | }
47 |
48 | @Override
49 | protected List parseResultSet(ResultSet resultSet) throws SQLException {
50 | List prescriptions = new ArrayList<>();
51 | while (resultSet.next()) {
52 | Long id = (resultSet.getLong("id"));
53 | String description = (resultSet.getString("description"));
54 | PersonFullName patientFullName = new PersonFullName(
55 | resultSet.getLong("patientID"),
56 | resultSet.getString("patientFirstName"),
57 | resultSet.getString("patientLastName"),
58 | resultSet.getString("patientPatronymic")
59 | );
60 | PersonFullName doctorFullName = new PersonFullName(
61 | resultSet.getLong("doctorID"),
62 | resultSet.getString("doctorFirstName"),
63 | resultSet.getString("doctorLastName"),
64 | resultSet.getString("doctorPatronymic")
65 | );
66 | DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
67 | LocalDate creationDate = LocalDate.parse(resultSet.getDate("creation_date").toLocalDate().format(formatter));
68 | Long validity = resultSet.getLong("validity");
69 | Priority priority = Priority.valueOf(resultSet.getString("priority"));
70 | Prescription prescription = new Prescription(id, description, patientFullName, doctorFullName, creationDate, validity, priority);
71 | prescriptions.add(prescription);
72 | }
73 | return prescriptions;
74 | }
75 |
76 | @Override
77 | protected void prepareStatementForUpdate(PreparedStatement preparedStatement, Prescription prescription) throws SQLException {
78 | if (prescription.getId() == null || prescription.getDescription() == null || prescription.getPatient() == null ||
79 | prescription.getPatient().getId() == null || prescription.getDoctor() == null ||
80 | prescription.getDoctor().getId() == null || prescription.getCreationDate() == null ||
81 | prescription.getValidity() == null || prescription.getPriority() == null) {
82 | throw new IllegalArgumentException("Some prescription object's fields are absent!");
83 | }
84 | preparedStatement.setString(1, prescription.getDescription());
85 | preparedStatement.setLong(2, prescription.getPatient().getId());
86 | preparedStatement.setLong(3, prescription.getDoctor().getId());
87 | preparedStatement.setDate(4, Date.valueOf(prescription.getCreationDate()));
88 | preparedStatement.setLong(5, prescription.getValidity());
89 | preparedStatement.setString(6, prescription.getPriority().toString());
90 | preparedStatement.setLong(7, prescription.getId());
91 | }
92 |
93 | @Override
94 | protected void prepareStatementForInsert(PreparedStatement preparedStatement, Prescription prescription)
95 | throws SQLException, IllegalArgumentException {
96 | if (prescription.getDescription() == null || prescription.getPatient() == null ||
97 | prescription.getPatient().getId() == null || prescription.getDoctor() == null ||
98 | prescription.getDoctor().getId() == null || prescription.getCreationDate() == null ||
99 | prescription.getValidity() == null || prescription.getPriority() == null) {
100 | throw new IllegalArgumentException("Some prescription object's fields are absent!");
101 | }
102 | preparedStatement.setString(1, prescription.getDescription());
103 | preparedStatement.setLong(2, prescription.getPatient().getId());
104 | preparedStatement.setLong(3, prescription.getDoctor().getId());
105 | preparedStatement.setDate(4, Date.valueOf(prescription.getCreationDate()));
106 | preparedStatement.setLong(5, prescription.getValidity());
107 | preparedStatement.setString(6, prescription.getPriority().toString());
108 | }
109 |
110 | public List getAllByFilters(String descriptionFilter, PersonFullName patientFilter, Priority priorityFilter)
111 | throws SQLException {
112 | StringBuilder filteredSelectQuery = new StringBuilder(getSelectQuery());
113 | List whereConditions = new ArrayList<>();
114 | if (descriptionFilter != null && !descriptionFilter.isEmpty()) {
115 | filteredSelectQuery.append(" AND description LIKE ? ");
116 | whereConditions.add("%" + descriptionFilter + "%");
117 | }
118 | if (patientFilter != null && patientFilter.getId() != null) {
119 | filteredSelectQuery.append(" AND Patient.id = ? ");
120 | whereConditions.add(patientFilter.getId().toString());
121 | }
122 | if (priorityFilter != null) {
123 | filteredSelectQuery.append(" AND priority = ? ");
124 | whereConditions.add(priorityFilter.name());
125 | }
126 | PreparedStatement preparedStatement = connection.prepareStatement(filteredSelectQuery.toString());
127 | for (int i = 0; i < whereConditions.size(); i++) {
128 | preparedStatement.setString(i + 1, whereConditions.get(i));
129 | }
130 | ResultSet resultSet = preparedStatement.executeQuery();
131 | List prescriptions = new ArrayList<>();
132 | while (resultSet.next()) {
133 | Long id = resultSet.getLong("id");
134 | String description = resultSet.getString("description");
135 | PersonFullName patientFullName = new PersonFullName(
136 | resultSet.getLong("PatientID"),
137 | resultSet.getString("patientFirstName"),
138 | resultSet.getString("patientLastName"),
139 | resultSet.getString("patientPatronymic")
140 | );
141 | PersonFullName doctorFullName = new PersonFullName(
142 | resultSet.getLong("PatientID"),
143 | resultSet.getString("doctorFirstName"),
144 | resultSet.getString("doctorLastName"),
145 | resultSet.getString("doctorPatronymic")
146 | );
147 | DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
148 | LocalDate creationDate = LocalDate.parse(resultSet.getDate("creation_date").toLocalDate().format(formatter), formatter);
149 | Long validity = resultSet.getLong("validity");
150 | Priority priority = Priority.valueOf(resultSet.getString("priority"));
151 | prescriptions.add(new Prescription(id, description, patientFullName, doctorFullName, creationDate, validity, priority));
152 | }
153 | return prescriptions;
154 | }
155 | }
--------------------------------------------------------------------------------
/src/main/java/com/zufar/testtask/ui/window/PrescriptionWindow.java:
--------------------------------------------------------------------------------
1 | package com.zufar.testtask.ui.window;
2 |
3 | import com.zufar.testtask.hsqldb.PrescriptionDao;
4 | import com.vaadin.data.util.converter.StringToDateConverter;
5 | import com.zufar.testtask.hsqldb.dto.PersonFullName;
6 | import com.zufar.testtask.model.Prescription;
7 | import com.zufar.testtask.hsqldb.DaoFactory;
8 | import com.zufar.testtask.model.Priority;
9 | import com.zufar.testtask.ui.layout.PrescriptionVerticalLayout;
10 | import com.vaadin.data.Property;
11 | import com.vaadin.data.Validator;
12 | import com.vaadin.data.util.converter.StringToLongConverter;
13 | import com.vaadin.data.validator.DateRangeValidator;
14 | import com.vaadin.data.validator.LongRangeValidator;
15 | import com.vaadin.data.validator.StringLengthValidator;
16 | import com.vaadin.event.FieldEvents;
17 | import com.vaadin.shared.ui.datefield.Resolution;
18 | import com.vaadin.ui.*;
19 |
20 | import java.sql.SQLException;
21 | import java.time.ZoneId;
22 | import java.util.*;
23 |
24 | public class PrescriptionWindow extends AbstractWindow {
25 |
26 | private TextField description = new TextField("Description:");
27 | private NativeSelect selectPatient = new NativeSelect("Patient:");
28 | private NativeSelect selectDoctor = new NativeSelect("Doctor:");
29 | private DateField creationDate = new DateField("Creation's date:", new Date());
30 | private TextField validity = new TextField("Validity (day's count):");
31 | private NativeSelect selectPriority = new NativeSelect("Priority:");
32 | private PrescriptionVerticalLayout prescriptionVerticalLayout;
33 | private Prescription selectedPrescription;
34 |
35 | public PrescriptionWindow(PrescriptionVerticalLayout prescriptionVerticalLayout, Prescription selectedPrescription) {
36 | this.prescriptionVerticalLayout = prescriptionVerticalLayout;
37 | this.selectedPrescription = selectedPrescription;
38 | this.verticalFields.addComponents(description, selectPatient, selectDoctor, creationDate, validity, selectPriority);
39 | configureComponents();
40 | }
41 |
42 | private void configureComponents() {
43 | description.focus();
44 | validity.setNullSettingAllowed(false);
45 | configureComponentsNullRepresentation();
46 | configureComponentsNullSellectionAllowed();
47 | configureComponentsWidth();
48 | configureComponentsValidators();
49 | configureComponentsValidationVisibility();
50 | configureComponentsRequired();
51 | configureComponentsTextChangeEventMode();
52 | configureComponentsChangeListeners();
53 | configureComponentsMaxLength();
54 | configureComponentsConverters();
55 | configureComponentsImmediate();
56 | configureComponentsValue();
57 | }
58 |
59 | private void configureComponentsNullRepresentation() {
60 | validity.setNullRepresentation("");
61 | description.setNullRepresentation("");
62 | }
63 |
64 | private void configureComponentsNullSellectionAllowed() {
65 | selectPatient.setNullSelectionAllowed(false);
66 | selectDoctor.setNullSelectionAllowed(false);
67 | selectPriority.setNullSelectionAllowed(false);
68 | }
69 |
70 | private void configureComponentsValue() {
71 | List patients;
72 | List doctors;
73 | try {
74 | patients = DaoFactory.getInstance().getPatientDao().getAllFullNames();
75 | selectPatient.addItems(patients);
76 | if (!patients.isEmpty()) {
77 | for (PersonFullName patient : patients) {
78 | if (patient != null) {
79 | selectPatient.setValue(patient);
80 | break;
81 | }
82 |
83 | }
84 | }
85 | doctors = DaoFactory.getInstance().getDoctorDao().getAllFullNames();
86 | selectDoctor.addItems(doctors);
87 | if (!doctors.isEmpty()) {
88 | for (PersonFullName doctor : doctors) {
89 | if (doctor != null) {
90 | selectDoctor.setValue(doctor);
91 | break;
92 | }
93 | }
94 | }
95 | selectPriority.addItems(Priority.NORMAL, Priority.SITO, Priority.STATIM);
96 | selectPriority.setValue(Priority.NORMAL);
97 | } catch (SQLException e) {
98 | prescriptionVerticalLayout.disableButtons();
99 | close();
100 | return;
101 | }
102 | //Если передан selectedPrescription, значит устанавливаем значения для окна EditPrescription
103 | if (selectedPrescription != null) {
104 | if (selectedPrescription.getCreationDate() == null || selectedPrescription.getValidity() == null ||
105 | selectedPrescription.getPatient() == null || selectedPrescription.getPatient().getId() == null ||
106 | selectedPrescription.getDoctor() == null || selectedPrescription.getDoctor().getId() == null) {
107 | throw new IllegalArgumentException("Some selectedRow's fields are absent!");
108 | }
109 | PersonFullName patient = patients.stream().
110 | filter(p -> Objects.equals(p.getId(), selectedPrescription.getPatient().getId())).findFirst().get();
111 | PersonFullName doctor = doctors.stream().
112 | filter(d -> Objects.equals(d.getId(), selectedPrescription.getDoctor().getId())).findFirst().get();
113 | selectPatient.setValue(patient);
114 | selectDoctor.setValue(doctor);
115 | description.setValue(selectedPrescription.getDescription());
116 | creationDate.setValue(Date.from(selectedPrescription.getCreationDate().atStartOfDay(ZoneId.systemDefault()).toInstant()));
117 | validity.setValue(selectedPrescription.getValidity().toString());
118 | selectPriority.setValue(selectedPrescription.getPriority());
119 | }
120 | }
121 |
122 | private void configureComponentsImmediate() {
123 | description.setImmediate(true);
124 | validity.setImmediate(true);
125 | creationDate.setImmediate(true);
126 | }
127 |
128 | private void configureComponentsConverters() {
129 | validity.setConverter(new StringToLongConverter());
130 | creationDate.setConverter(new StringToDateConverter().getModelType());
131 | }
132 |
133 | private void configureComponentsMaxLength() {
134 | description.setMaxLength(50);
135 | validity.setMaxLength(18);
136 | }
137 |
138 | private void configureComponentsChangeListeners() {
139 | selectPriority.addValueChangeListener(event -> actionAfterSelectChangeEvent(event, selectPriority));
140 | selectPatient.addValueChangeListener(event -> actionAfterSelectChangeEvent(event, selectPatient));
141 | selectDoctor.addValueChangeListener(event -> actionAfterSelectChangeEvent(event, selectDoctor));
142 | description.addTextChangeListener(event -> actionAfterTextChangeEvent(event, description));
143 | validity.addTextChangeListener(event -> actionAfterTextChangeEvent(event, validity));
144 | creationDate.addValueChangeListener(event -> actionAfterDateChangeEvent());
145 | }
146 |
147 | private void configureComponentsTextChangeEventMode() {
148 | description.setTextChangeEventMode(AbstractTextField.TextChangeEventMode.EAGER);
149 | validity.setTextChangeEventMode(AbstractTextField.TextChangeEventMode.EAGER);
150 | }
151 |
152 | private void configureComponentsRequired() {
153 | selectPriority.setRequired(true);
154 | selectPatient.setRequired(true);
155 | selectDoctor.setRequired(true);
156 | description.setRequired(true);
157 | validity.setRequired(true);
158 | }
159 |
160 | private void configureComponentsValidationVisibility() {
161 | description.setValidationVisible(true);
162 | validity.setValidationVisible(true);
163 | selectPatient.setValidationVisible(true);
164 | selectDoctor.setValidationVisible(true);
165 | selectPriority.setValidationVisible(true);
166 | creationDate.setValidationVisible(true);
167 | }
168 |
169 | private void configureComponentsValidators() {
170 | validity.addValidator(new LongRangeValidator("Negative value in field!", 0L, Long.MAX_VALUE));
171 | creationDate.addValidator(new DateRangeValidator("Wrong date!", null, null, Resolution.DAY));
172 | description.addValidator(new StringLengthValidator("Field is empty!", 1, 50, false));
173 | }
174 |
175 | private void configureComponentsWidth() {
176 | selectPriority.setWidth("300");
177 | selectPatient.setWidth("300");
178 | creationDate.setWidth("300");
179 | selectDoctor.setWidth("300");
180 | description.setWidth("300");
181 | validity.setWidth("300");
182 | }
183 |
184 | void actionAfterClickOkButton(Button.ClickEvent clickEvent) {
185 | prescriptionVerticalLayout.disableButtons();
186 | Prescription prescription = new Prescription(
187 | description.getValue(),
188 | ((PersonFullName) selectPatient.getValue()),
189 | ((PersonFullName) selectDoctor.getValue()),
190 | creationDate.getValue().toInstant().atZone(ZoneId.systemDefault()).toLocalDate(),
191 | (Long) validity.getConvertedValue(),
192 | Priority.valueOf(selectPriority.getValue().toString())
193 | );
194 | try {
195 | PrescriptionDao prescriptionDao = DaoFactory.getInstance().getPrescriptionDao();
196 | if (selectedPrescription == null) {
197 | prescriptionDao.create(prescription);
198 | } else {
199 | if (selectedPrescription.getId() == null) {
200 | throw new IllegalArgumentException();
201 | }
202 | prescription.setId(selectedPrescription.getId());
203 | prescriptionDao.update(prescription);
204 | }
205 | getUI().getPrescriptionVerticalLayout().refreshGrid(null);
206 | prescriptionVerticalLayout.refreshGrid(null);
207 | close();
208 | } catch (SQLException e) {
209 | Notification.show("Taking action for this prescription is impossible!", "There are some problems with the database.",
210 | Notification.Type.ERROR_MESSAGE);
211 | }
212 | }
213 |
214 | private void actionAfterTextChangeEvent(FieldEvents.TextChangeEvent event, TextField textField) {
215 | textField.setValue(event.getText());
216 | textField.setCursorPosition(event.getCursorPosition());
217 | enableButtonByValidityComponents();
218 | }
219 |
220 | private void actionAfterSelectChangeEvent(Property.ValueChangeEvent event, NativeSelect select) {
221 | select.setValue(event.getProperty().getValue());
222 | enableButtonByValidityComponents();
223 | }
224 |
225 | private void actionAfterDateChangeEvent() {
226 | if (creationDate.isEmpty()) {
227 | if (selectedPrescription != null && selectedPrescription.getCreationDate() != null) {
228 | creationDate.setValue(Date.from(selectedPrescription.getCreationDate().atStartOfDay(ZoneId.systemDefault()).toInstant()));
229 | } else {
230 | creationDate.setValue(new Date());
231 | }
232 | }
233 | enableButtonByValidityComponents();
234 | }
235 |
236 | private void enableButtonByValidityComponents() {
237 | if (description.getValue() == null || description.getValue().isEmpty() ||
238 | selectPatient.getValue() == null || selectPatient.getValue().toString().isEmpty() ||
239 | selectDoctor.getValue() == null || selectDoctor.getValue().toString().isEmpty() ||
240 | creationDate.getValue() == null || creationDate.getValue().toString().isEmpty() ||
241 | selectPriority.getValue() == null || selectPriority.getValue().toString().isEmpty()) {
242 | okButton.setEnabled(false);
243 | return;
244 | }
245 | try {
246 | creationDate.validate();
247 | description.validate();
248 | validity.validate();
249 | okButton.setEnabled(true);
250 | } catch (Validator.InvalidValueException e) {
251 | okButton.setEnabled(false);
252 | }
253 | }
254 | }
--------------------------------------------------------------------------------