diff --git a/src/main/java/pl/koder95/eme/dfs/BookType.java b/src/main/java/pl/koder95/eme/dfs/BookType.java new file mode 100644 index 0000000..1f42a98 --- /dev/null +++ b/src/main/java/pl/koder95/eme/dfs/BookType.java @@ -0,0 +1,8 @@ +package pl.koder95.eme.dfs; + +public enum BookType { + LIBER_BAPTISMORUM, + LIBER_CONFIRMATORUM, + LIBER_MATRIMONIORUM, + LIBER_DEFUNCTORUM +} diff --git a/src/main/java/pl/koder95/eme/dfs/IndexNodeInterpreter.java b/src/main/java/pl/koder95/eme/dfs/IndexNodeInterpreter.java new file mode 100644 index 0000000..6567c70 --- /dev/null +++ b/src/main/java/pl/koder95/eme/dfs/IndexNodeInterpreter.java @@ -0,0 +1,8 @@ +package pl.koder95.eme.dfs; + +import java.util.Map; +import org.w3c.dom.Node; + +public interface IndexNodeInterpreter { + Map interpret(Node node); +} diff --git a/src/main/java/pl/koder95/eme/dfs/impl/IndexNodeInterpreterImpl.java b/src/main/java/pl/koder95/eme/dfs/impl/IndexNodeInterpreterImpl.java new file mode 100644 index 0000000..f2975cb --- /dev/null +++ b/src/main/java/pl/koder95/eme/dfs/impl/IndexNodeInterpreterImpl.java @@ -0,0 +1,27 @@ +package pl.koder95.eme.dfs.impl; + +import java.util.HashMap; +import java.util.Map; + +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Node; +import pl.koder95.eme.dfs.IndexNodeInterpreter; + +public class IndexNodeInterpreterImpl implements IndexNodeInterpreter { + @Override + public Map interpret(Node node) { + if (node == null || node.getNodeName().equalsIgnoreCase("index")) { + throw new IllegalArgumentException("Node is null or node is not an index"); + } + Map data = new HashMap<>(); + NamedNodeMap attrs = node.getAttributes(); // pobiera listę atrybutów + while (attrs.getLength() > 0) { + Node attr = attrs.item(0); // pobiera pierwszy atrybut + String key = attr.getNodeName(); // - nazwa atrybutu + String value = attr.getTextContent(); // - wartość atrybutu + data.put(key, value); // dodanie nazwy i wartości atrybutu do danych + attrs.removeNamedItem(key); // usuwa odczytany atrybut + } + return data; + } +} diff --git a/src/main/java/pl/koder95/eme/factory/IndexFactory.java b/src/main/java/pl/koder95/eme/factory/IndexFactory.java new file mode 100644 index 0000000..dc10964 --- /dev/null +++ b/src/main/java/pl/koder95/eme/factory/IndexFactory.java @@ -0,0 +1,11 @@ +package pl.koder95.eme.factory; + +import pl.koder95.eme.dfs.BookType; +import pl.koder95.eme.dfs.Index; + +import java.util.Map; + +public interface IndexFactory { + + Index create(Map data); +} diff --git a/src/main/java/pl/koder95/eme/factory/impl/BasicIndexFactory.java b/src/main/java/pl/koder95/eme/factory/impl/BasicIndexFactory.java new file mode 100644 index 0000000..79e33fb --- /dev/null +++ b/src/main/java/pl/koder95/eme/factory/impl/BasicIndexFactory.java @@ -0,0 +1,30 @@ +package pl.koder95.eme.factory.impl; + +import java.util.Map; +import java.util.Set; +import java.util.function.Function; + +import pl.koder95.eme.dfs.Book; +import pl.koder95.eme.dfs.BookType; +import pl.koder95.eme.dfs.Index; +import pl.koder95.eme.dfs.IndexNodeInterpreter; +import pl.koder95.eme.factory.IndexFactory; + +public class BasicIndexFactory implements IndexFactory { + + private final Function, BookType> bookTypeMatcher; + private final Map bookMap; + + public BasicIndexFactory(Function, BookType> bookTypeMatcher, Map bookMap) { + this.bookTypeMatcher = bookTypeMatcher; + this.bookMap = bookMap; + } + + @Override + public Index create(Map data) { + if (data == null) return null; + BookType bookType = bookTypeMatcher.apply(data.keySet()); + if (bookType == null) return null; + return Index.create(bookMap.get(bookType), data); + } +} diff --git a/src/main/java/pl/koder95/eme/factory/impl/StandardIndexFactory.java b/src/main/java/pl/koder95/eme/factory/impl/StandardIndexFactory.java new file mode 100644 index 0000000..1571feb --- /dev/null +++ b/src/main/java/pl/koder95/eme/factory/impl/StandardIndexFactory.java @@ -0,0 +1,35 @@ +package pl.koder95.eme.factory.impl; + +import pl.koder95.eme.dfs.Book; +import pl.koder95.eme.dfs.BookType; + +import java.util.Arrays; +import java.util.Map; +import java.util.Set; +import java.util.function.BiPredicate; + +public class StandardIndexFactory extends BasicIndexFactory { + + public StandardIndexFactory(BiPredicate, BookType> bookTypePattern) { + super(strings -> Arrays.stream(BookType.values()) + .filter(bookType -> bookTypePattern.test(strings, bookType)) + .findFirst().orElseThrow(), + Map.of( + BookType.LIBER_BAPTISMORUM, new Book("Księga ochrzczonych"), + BookType.LIBER_CONFIRMATORUM, new Book("Księga bierzmowanych"), + BookType.LIBER_MATRIMONIORUM, new Book("Księga zaślubionych"), + BookType.LIBER_DEFUNCTORUM, new Book("Księga zmarłych") + ) + ); + } + + public StandardIndexFactory() { + this((strings, bookType) -> switch (bookType) { + case null -> false; + case LIBER_CONFIRMATORUM -> strings.contains("confirmation-name"); + case LIBER_DEFUNCTORUM -> strings.contains("death-date-time"); + case LIBER_MATRIMONIORUM -> strings.contains("husband-surname"); + default -> strings.contains("surname"); + }); + } +} diff --git a/src/main/java/pl/koder95/eme/fx/PersonalDataView.java b/src/main/java/pl/koder95/eme/fx/PersonalDataView.java index 534bb57..1eb1f85 100644 --- a/src/main/java/pl/koder95/eme/fx/PersonalDataView.java +++ b/src/main/java/pl/koder95/eme/fx/PersonalDataView.java @@ -9,6 +9,7 @@ import javafx.scene.control.Label; import javafx.scene.control.TextField; import javafx.scene.layout.BorderPane; +import javafx.scene.control.*; import org.controlsfx.control.textfield.AutoCompletionBinding; import org.controlsfx.control.textfield.TextFields; import pl.koder95.eme.application.AppCloseService; @@ -71,32 +72,41 @@ public PersonalDataView(PersonalDataQueryService personalDataQueryService, private Label numberOfActs; @FXML - private Object searching; + private TextField searching; @Override public void initialize(URL location, ResourceBundle resources) { - if (searching instanceof TextField) { - TextField field = (TextField) searching; - AutoCompletionBinding autoCompletionBinding = TextFields.bindAutoCompletion( - field, - personalDataQueryService.getSuggestionProvider(), - personalDataQueryService.getPersonalDataConverter() - ); - autoCompletionBinding.setOnAutoCompleted(event -> setPersonalDataModel(event.getCompletion())); - field.setOnAction(event -> setPersonalDataModel( - personalDataQueryService.fromText(field.getText()) - )); - field.textProperty().addListener( - (observable, oldValue, newValue) -> { - if (oldValue.length() < newValue.length()) { - field.setText(newValue.toUpperCase()); - } - } - ); - } + installCabinetAnalyzer(); + } + + private void installCabinetAnalyzer() { + setupAutoCompletion(); + setupInputActions(); numberOfActs.setText(String.valueOf(personalDataQueryService.getNumberOfActs())); } + private void setupAutoCompletion() { + AutoCompletionBinding binding = TextFields.bindAutoCompletion( + searching, + personalDataQueryService.getSuggestionProvider(), + personalDataQueryService.getPersonalDataConverter() + ); + binding.setOnAutoCompleted(event -> setPersonalDataModel(event.getCompletion())); + } + + private void setupInputActions() { + searching.setOnAction(event -> setPersonalDataModel( + personalDataQueryService.getPersonalDataConverter().fromString(searching.getText()) + )); + searching.textProperty().addListener( + (observable, oldValue, newValue) -> { + if (oldValue.length() < newValue.length()) { + searching.setText(newValue.toUpperCase()); + } + } + ); + } + private void setPersonalDataModel(PersonalDataModel model) { PersonalDataPresentation viewData = personalDataQueryService.toPresentation(model); this.personalData.setText(viewData.fullName()); @@ -105,7 +115,6 @@ private void setPersonalDataModel(PersonalDataModel model) { this.marriage.setText(viewData.getMarriageAN()); this.decease.setText(viewData.getDeceaseAN()); } - /** * Obsługuje próbę zamknięcia aplikacji z potwierdzeniem. */ @@ -116,7 +125,7 @@ public void close(ActionEvent actionEvent) { /** * Ponownie wczytuje dane indeksów i odświeża licznik aktów. */ - public void reload(ActionEvent actionEvent) { + public void reload() { Scene scene = main.getScene(); if (scene != null) { Dialog dialog = dialogs.createProgressDialog(scene, bundle.getString("FX_RELOAD_PROGRESS_MESSAGE")); diff --git a/src/main/java/pl/koder95/eme/fx/ProgressDialog.java b/src/main/java/pl/koder95/eme/fx/ProgressDialog.java new file mode 100644 index 0000000..5ccc3ca --- /dev/null +++ b/src/main/java/pl/koder95/eme/fx/ProgressDialog.java @@ -0,0 +1,67 @@ +package pl.koder95.eme.fx; + +import javafx.application.Platform; +import javafx.geometry.Pos; +import javafx.scene.Parent; +import javafx.scene.control.Dialog; +import javafx.scene.control.DialogPane; +import javafx.scene.control.Label; +import javafx.scene.control.ProgressIndicator; +import javafx.scene.layout.VBox; +import javafx.scene.text.Font; +import javafx.scene.text.FontWeight; +import pl.koder95.eme.dfs.IndexList; + +import java.util.concurrent.atomic.AtomicLong; + +public class ProgressDialog extends Dialog { + private static final AtomicLong PROGRESS_DIALOG_THREAD_SEQ = new AtomicLong(); + + private ProgressDialog() { + this.setDialogPane(createDialogPane()); + setOnShown(event -> Platform.runLater(createProgressThread()::start)); + } + + private Thread createProgressThread() { + return new Thread(() -> { + reloadAllIndexLists(); + Platform.runLater(() -> { + setResult(true); + close(); + }); + }, "Progress Dialog Thread #" + PROGRESS_DIALOG_THREAD_SEQ.incrementAndGet()); + } + + private DialogPane createDialogPane() { + ProgressIndicator indicator = new ProgressIndicator(ProgressIndicator.INDETERMINATE_PROGRESS); + Label label = new Label("Czekaj..."); + label.setFont(Font.font(label.getFont().getFamily(), FontWeight.BOLD, 24)); + DialogPane pane = new DialogPane(); + pane.setContent(createMainPane(indicator, label)); + return pane; + } + + private Parent createMainPane(ProgressIndicator indicator, Label label) { + VBox main = new VBox(indicator, label); + main.setMaxWidth(Double.MAX_VALUE); + main.setSpacing(10); + main.setFillWidth(true); + main.setAlignment(Pos.CENTER); + return main; + } + + private static void reloadAllIndexLists() { + for (IndexList value : IndexList.values()) { + reload(value); + } + } + + private static void reload(IndexList value) { + value.clear(); + value.load(); + } + + public static void start() { + Platform.runLater(() -> new ProgressDialog().showAndWait()); + } +} diff --git a/src/main/java/pl/koder95/eme/model/PersonalData.java b/src/main/java/pl/koder95/eme/model/PersonalData.java new file mode 100644 index 0000000..76f727e --- /dev/null +++ b/src/main/java/pl/koder95/eme/model/PersonalData.java @@ -0,0 +1,40 @@ +package pl.koder95.eme.model; + +import pl.koder95.eme.core.spi.PersonalDataModel; + +public record PersonalData(String surname, String name, + String ban, String can, String man, String dan) + implements PersonalDataModel { + private static final String NOMEN = "N."; + private static final String EAN = "–"; + + @Override + public String getSurname() { + return surname == null || surname.isBlank() ? NOMEN : surname; + } + + @Override + public String getName() { + return name == null || name.isBlank() ? NOMEN : name; + } + + @Override + public String getBaptismAN() { + return ban == null || ban.isBlank() ? EAN : ban; + } + + @Override + public String getConfirmationAN() { + return can == null || can.isBlank() ? EAN : can; + } + + @Override + public String getMarriageAN() { + return man == null || man.isBlank() ? EAN : man; + } + + @Override + public String getDeceaseAN() { + return dan == null || dan.isBlank() ? EAN : dan; + } +} diff --git a/src/main/java/pl/koder95/eme/service/DataService.java b/src/main/java/pl/koder95/eme/service/DataService.java new file mode 100644 index 0000000..426cf80 --- /dev/null +++ b/src/main/java/pl/koder95/eme/service/DataService.java @@ -0,0 +1,13 @@ +package pl.koder95.eme.service; + +import pl.koder95.eme.core.spi.PersonalDataModel; + +import java.util.Collection; +import java.util.function.Predicate; + +public interface DataService { + void load(); + void save(); + Collection findPeople(Predicate predicate); + Collection findPeople(String userText, boolean cancelled); +}