1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package cz.zcu.mre.sparkle.gui.dialogs.storage;
21
22 import cz.zcu.mre.sparkle.Messages;
23 import cz.zcu.mre.sparkle.data.PrefixesStorage;
24 import cz.zcu.mre.sparkle.gui.dialogs.other.ErrorDialog;
25 import cz.zcu.mre.sparkle.gui.tools.AbstractDialogController;
26 import cz.zcu.mre.sparkle.gui.tools.FormControllerFactory;
27 import cz.zcu.mre.sparkle.gui.tools.ShortCutHandler;
28 import cz.zcu.mre.sparkle.tools.Definitions;
29 import cz.zcu.mre.sparkle.tools.IO;
30 import javafx.beans.property.SimpleStringProperty;
31 import javafx.collections.FXCollections;
32 import javafx.collections.ObservableList;
33 import javafx.event.ActionEvent;
34 import javafx.fxml.FXML;
35 import javafx.scene.control.*;
36 import javafx.scene.control.TableColumn.CellEditEvent;
37 import javafx.scene.control.cell.PropertyValueFactory;
38 import javafx.scene.control.cell.TextFieldTableCell;
39 import javafx.scene.input.KeyCode;
40 import javafx.stage.Window;
41 import java.io.File;
42 import java.io.IOException;
43 import java.util.Collection;
44 import java.util.HashSet;
45 import java.util.List;
46 import java.util.Set;
47 import java.util.logging.Level;
48 import java.util.logging.Logger;
49
50
51
52
53
54
55
56
57 public final class PrefixesDialog
58 extends AbstractDialogController {
59
60 private static final Logger LOG = Logger.getLogger(PrefixesDialog.class.getName());
61 public static final int CSV_COLUMN_COUNT = 5;
62
63 enum CSV_FILE_ROW {
64 NAME(0), DATE(1), PREFIX(2), IRI(3), ALTERNATIVE_IRI(4);
65
66 private int index;
67
68 CSV_FILE_ROW(int index) {
69 this.index = index;
70 }
71
72 public int getIndex() {
73 return index;
74 }
75 }
76
77 @FXML
78 private TextField prefixTextField, iriTextField, alternativeIriTextField;
79 @FXML
80 private TableView<TableRow> prefixesTable;
81 @FXML
82 private TableColumn<TableRow, String> prefixColumn, iriColumn, alternativeIriColumn;
83 @FXML
84 private Button removeSelectedButton, addButton;
85
86 private PrefixesStorage prefixesStorage = null;
87
88
89
90
91
92
93 private final Set<String> prefixesInUse = new HashSet<>();
94
95 @Override
96 protected final void onDialogInitialized() {
97 setTitle(Messages.getString("MANAGE_PREFIXES"));
98
99 prefixColumn.setCellFactory(TextFieldTableCell.forTableColumn());
100 prefixColumn.setCellValueFactory(new PropertyValueFactory<>("prefix"));
101 iriColumn.setCellFactory(TextFieldTableCell.forTableColumn());
102 iriColumn.setCellValueFactory(new PropertyValueFactory<>("iri"));
103 alternativeIriColumn.setCellFactory(TextFieldTableCell.forTableColumn());
104 alternativeIriColumn.setCellValueFactory(new PropertyValueFactory<>("alternativeIri"));
105
106 prefixesTable.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
107 removeSelectedButton.disableProperty().bind(prefixesTable.getSelectionModel().selectedItemProperty().isNull());
108
109 addButton.disableProperty()
110 .bind(prefixTextField.textProperty().isEmpty().or(iriTextField.textProperty().isEmpty()));
111
112
113 getShortCutHandler();
114 }
115
116
117
118
119 private void getShortCutHandler() {
120 new ShortCutHandler(KeyCode.DELETE) {
121
122 @Override
123 public final boolean handle(final Object source) {
124 if (source != prefixesTable) {
125 return false;
126 }
127
128 if (prefixesTable.getSelectionModel().isEmpty()) {
129 return false;
130 }
131
132 removeSelectedButtonOnAction();
133 return true;
134 }
135 }.attach(prefixesTable);
136 }
137
138
139
140
141 @FXML
142 private void addButtonOnAction() {
143 final String prefix = prefixTextField.getText().trim();
144 final String iri = iriTextField.getText().trim();
145 final String alternativeIri = alternativeIriTextField.getText().trim();
146
147 if (!formCheck(prefix, iri, alternativeIri)) {
148 return;
149 }
150
151 addPrefix(prefix, iri, alternativeIri);
152
153 prefixTextField.clear();
154 iriTextField.clear();
155 alternativeIriTextField.clear();
156 }
157
158
159
160
161
162
163
164
165 private void addPrefix(String prefix, String iri, String alternativeIri) {
166
167 final Collection<TableRow> items = prefixesTable.getItems();
168 final int index = items.size();
169
170 items.add(new TableRow(prefix, iri, alternativeIri));
171 prefixesStorage.addPrefix(prefix, iri, alternativeIri);
172
173 prefixesTable.scrollTo(index);
174 prefixesTable.getSelectionModel().clearAndSelect(index);
175 }
176
177
178
179
180
181
182
183
184
185
186 private boolean formCheck(String prefix, String iri, String alternativeIri) {
187 if (prefix.isEmpty()) {
188 showErrorDialog("WARNING", Messages.getString("PREFIX_CANNOT_BE_EMPTY"));
189 prefixTextField.requestFocus();
190 return false;
191 }
192
193 if (prefixesStorage.getPrefixToIri().containsKey(prefix)) {
194 showErrorDialog("WARNING", Messages.getString("PREFIX_ALREADY_EXISTS"));
195 prefixTextField.requestFocus();
196 return false;
197 }
198
199 if (prefixesStorage.getNsURIPrefix(iri) != null) {
200 showErrorDialog("WARNING", String.format(Messages.getString("IRI_ALREADY_EXISTS"), prefix));
201 prefixTextField.requestFocus();
202 return false;
203 }
204
205 if (prefixesStorage.getNsURIPrefix(alternativeIri) != null) {
206 showErrorDialog("WARNING", String.format(Messages.getString("ALT_IRI_ALREADY_EXISTS"), prefix));
207 prefixTextField.requestFocus();
208 return false;
209 }
210
211 if (iri.isEmpty()) {
212 showErrorDialog("WARNING", Messages.getString("IRI_CANNOT_BE_EMPTY"));
213 prefixTextField.requestFocus();
214 return false;
215 }
216
217 return true;
218 }
219
220
221
222
223 @FXML
224 private void removeSelectedButtonOnAction() {
225
226 final Collection<TableRow> selectedItems
227 = FXCollections.observableArrayList(prefixesTable.getSelectionModel().getSelectedItems());
228 if ((selectedItems.isEmpty())) {
229 return;
230 }
231
232 final Collection<TableRow> items = prefixesTable.getItems();
233 boolean anythingRemoved = false;
234
235 for (final TableRow item : selectedItems) {
236 final String prefix = item.getPrefix();
237
238 if (prefixesInUse.contains(prefix)) {
239 showErrorDialog("WARNING", String.format(Messages.getString("PREFIX_IN_USE_REMOVAL"), prefix));
240 continue;
241 }
242 prefixesStorage.removeNsPrefix(prefix);
243 items.remove(item);
244 anythingRemoved = true;
245 }
246
247 if (anythingRemoved) {
248 prefixesTable.getSelectionModel().clearSelection();
249 }
250 }
251
252
253
254
255 @FXML
256 private void restorePrefixesButtonOnAction() {
257 prefixesStorage.add(PrefixesStorage.getBuiltIn());
258 setPrefixesStorage(prefixesStorage);
259 }
260
261
262
263
264
265
266 @FXML
267 public void loadFromFileButtonOnAction(ActionEvent actionEvent) {
268 List<File> files = IO.openCsvFile(this.getStage(), "", false);
269 if (files == null || files.isEmpty()) {
270 return;
271 }
272 List<String> rows = IO.readStringsFromFile(files.get(0));
273 if (rows == null) {
274 return;
275 }
276 for (String row : rows) {
277 String[] values = row.split(Definitions.SEMICOLON);
278 if (values.length < CSV_COLUMN_COUNT) {
279 ErrorDialog.open(this.getStage(), Messages.getString("WARNING"),
280 String.format(Messages.getString("LOAD_PREFIX_FROM_FILE_ERROR"), row));
281 continue;
282 }
283
284 String prefix = values[CSV_FILE_ROW.PREFIX.getIndex()];
285 String iri = values[CSV_FILE_ROW.IRI.getIndex()];
286 String altIri = values[CSV_FILE_ROW.ALTERNATIVE_IRI.getIndex()];
287 altIri = altIri.equals("-") ? "" : altIri;
288
289 if (prefixesStorage.getPrefixToIri().containsKey(prefix)) {
290
291 continue;
292 }
293
294
295 if (prefixesStorage.getNsURIPrefix(iri) != null) {
296
297 continue;
298 }
299
300 if (prefixesStorage.getNsURIPrefix(altIri) != null) {
301
302 continue;
303 }
304
305 addPrefix(prefix, iri, altIri);
306 }
307
308
309 }
310
311
312
313
314 @FXML
315 private void closeButtonOnAction() {
316 close();
317 }
318
319
320
321
322 private void setPrefixesStorage(final PrefixesStorage prefixesStorage) {
323 final ObservableList<TableRow> data = FXCollections.observableArrayList();
324
325 prefixesStorage.getPrefixToIri().forEach((key, value) -> {
326 data.add(new TableRow(key, value, prefixesStorage.getIriToAlternativeIri().get(value)));
327 });
328 prefixesTable.setItems(data);
329
330 this.prefixesStorage = prefixesStorage;
331 }
332
333
334
335
336
337 public static final void open(final Window owner, final PrefixesStorage prefixesStorage) {
338 open(owner, prefixesStorage, null);
339 }
340
341
342
343
344
345
346 public static final void open(final Window owner, final PrefixesStorage prefixesStorage,
347 final Set<String> prefixesInUse) {
348 try {
349 final PrefixesDialog dlg = FormControllerFactory.load(owner, PrefixesDialog.class);
350 dlg.setPrefixesStorage(prefixesStorage);
351 dlg.setPrefixesInUse(prefixesInUse);
352 dlg.showAndWait();
353 } catch (final IOException e) {
354 LOG.log(Level.SEVERE, "Exception: ", e);
355 }
356 }
357
358
359
360
361
362
363 private void setPrefixesInUse(final Set<String> prefixesInUse) {
364 this.prefixesInUse.clear();
365 if (prefixesInUse != null) {
366 this.prefixesInUse.addAll(prefixesInUse);
367 }
368 }
369
370
371
372
373 @FXML
374 private void prefixOnEditCommit(final CellEditEvent<TableRow, String> event) {
375 final String newValue = event.getNewValue().trim();
376 final String oldValue = event.getOldValue();
377 boolean error = false;
378
379 if (prefixesInUse.contains(oldValue)) {
380
381 error = true;
382 showErrorDialog("ERROR", String.format(Messages.getString("PREFIX_IN_USE_RENAMING"),
383 oldValue));
384 }
385
386 if (newValue.isEmpty()) {
387 error = true;
388 showErrorDialog("ERROR", Messages.getString("PREFIX_CANNOT_BE_EMPTY"));
389 } else if (prefixesStorage.getPrefixToIri().containsKey(newValue)) {
390 error = true;
391 showErrorDialog("ERROR", Messages.getString("PREFIX_ALREADY_EXISTS"));
392 }
393
394 final TableRow item = event.getRowValue();
395
396 if (error) {
397 item.setPrefix("");
398 item.setPrefix(oldValue);
399 return;
400 }
401
402 item.setPrefix(newValue);
403 prefixesStorage.renamePrefix(oldValue, newValue);
404
405 prefixesTable.requestFocus();
406 }
407
408
409
410
411 @FXML
412 private void iriOnEditCommit(final CellEditEvent<TableRow, String> event) {
413 editIri(event, true);
414 }
415
416 @FXML
417 private void alternativeIriOnEditCommit(final CellEditEvent<TableRow, String> event) {
418 editIri(event, false);
419 }
420
421
422
423
424
425
426
427 private void editIri(CellEditEvent<TableRow, String> event, boolean editIri) {
428 final String newValue = event.getNewValue().trim();
429 final String oldValue = event.getOldValue();
430 boolean error = false;
431
432 if (editIri && newValue.isEmpty()) {
433 error = true;
434 showErrorDialog("ERROR", Messages.getString("IRI_CANNOT_BE_EMPTY"));
435 }
436
437 final TableRow item = event.getRowValue();
438
439 if (error) {
440 item.setIri("");
441 item.setIri(oldValue);
442 return;
443 }
444
445 if (editIri) {
446 item.setIri(newValue);
447 prefixesStorage.setNsPrefix(item.getPrefix(), newValue);
448 } else {
449 item.setAlternativeIri(newValue);
450 prefixesStorage.setAlternativeIri(item.getIri(), newValue);
451 }
452
453 prefixesTable.requestFocus();
454 }
455
456
457
458
459
460
461
462 private void showErrorDialog(String titleKey, String message) {
463 ErrorDialog.open(getStage(), Messages.getString(titleKey), message);
464 }
465
466
467
468
469 public static final class TableRow {
470
471 private final SimpleStringProperty prefix;
472 private final SimpleStringProperty iri;
473 private final SimpleStringProperty alternativeIri;
474
475 TableRow() {
476 prefix = new SimpleStringProperty();
477 iri = new SimpleStringProperty();
478 alternativeIri = new SimpleStringProperty();
479 }
480
481 TableRow(final String prefix, final String iri, final String alternativeIri) {
482 this.prefix = new SimpleStringProperty(prefix);
483 this.iri = new SimpleStringProperty(iri);
484 this.alternativeIri = new SimpleStringProperty(alternativeIri);
485 }
486
487 public final String getPrefix() {
488 return prefix.get();
489 }
490
491 public final void setPrefix(final String value) {
492 prefix.set(value);
493 }
494
495 public final String getIri() {
496 return iri.get();
497 }
498
499 public final void setIri(final String value) {
500 iri.set(value);
501 }
502
503 public String getAlternativeIri() {
504 return alternativeIri.get();
505 }
506
507 public void setAlternativeIri(final String value) {
508 alternativeIri.set(value);
509 }
510
511 }
512 }