Skip to content

Commit f8c9dac

Browse files
committed
#165: fix issue where all application.properties were persisted in separate file. adapt layout of rest api settings.
1 parent 20b8444 commit f8c9dac

File tree

4 files changed

+115
-171
lines changed

4 files changed

+115
-171
lines changed

src/main/java/de/doubleslash/keeptime/view/LoginController.java

Lines changed: 0 additions & 26 deletions
This file was deleted.

src/main/java/de/doubleslash/keeptime/view/SettingsController.java

Lines changed: 35 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@
4646
import javafx.collections.FXCollections;
4747
import javafx.collections.ObservableList;
4848
import javafx.fxml.FXML;
49-
import javafx.fxml.FXMLLoader;
5049
import javafx.scene.control.*;
5150
import javafx.scene.control.Alert.AlertType;
5251
import javafx.scene.control.cell.PropertyValueFactory;
@@ -173,21 +172,20 @@ public class SettingsController {
173172
@FXML
174173
private PasswordField authPassword;
175174

176-
private ToggleGroup toggleGroup;
177-
178175
@FXML
179-
private RadioButton radioApiOff;
176+
private CheckBox activateRestApiCheckBox;
180177

181178
@FXML
182-
private RadioButton radioApiOn;
179+
private Hyperlink swaggerHyperLink;
183180

184181
@FXML
185182
private TextField authPort;
186183

187-
private String propertiesFilePath = "application.properties";
184+
private final String propertiesFilePath = "application.properties";
188185

189186
private static final String GITHUB_PAGE = "https://www.github.com/doubleSlashde/KeepTime";
190187
private static final String GITHUB_ISSUE_PAGE = GITHUB_PAGE + "/issues";
188+
191189
private static final Color HYPERLINK_COLOR = Color.rgb(0, 115, 170);
192190
private final ApplicationProperties applicationProperties;
193191

@@ -238,51 +236,43 @@ private void initialize() {
238236
initExportButton();
239237
initImportButton();
240238

241-
toggleGroup = new ToggleGroup();
242-
radioApiOff.setToggleGroup(toggleGroup);
243-
radioApiOn.setToggleGroup(toggleGroup);
244-
245-
Properties properties = new Properties();
246239
try (FileInputStream input = new FileInputStream(propertiesFilePath)) {
240+
Properties properties = new Properties();
247241
properties.load(input);
248-
String apistatus = properties.getProperty("api");
249-
if (apistatus != null) {
250-
if (apistatus.equals("ON")) {
251-
radioApiOn.setSelected(true);
252-
radioApiOff.setSelected(false);
242+
String apiStatus = properties.getProperty("api");
243+
if (apiStatus != null) {
244+
if (apiStatus.equals("ON")) {
245+
activateRestApiCheckBox.setSelected(true);
253246
String port = properties.getProperty("server.port");
254247
String userName = properties.getProperty("spring.security.user.name");
255248
String userPassword = properties.getProperty("spring.security.user.password");
256249

257250
if (port != null) {
258251
authPort.setText(port);
259-
260252
}
261253
if (userName!= null) {
262-
authName.setText(LoginController.extractValue(userName));
263-
authPassword.setText(LoginController.extractValue(userPassword));
264-
254+
authName.setText(userName);
255+
authPassword.setText(userPassword);
265256
}
266-
} else if (apistatus.equals("OFF")) {
267-
radioApiOn.setSelected(false);
268-
radioApiOff.setSelected(true);
257+
} else if (apiStatus.equals("OFF")) {
258+
activateRestApiCheckBox.setSelected(false);
269259
}
270260
}
271261
} catch (IOException e) {
272-
LOG.warn("There is currently no application.properties available");
262+
LOG.debug(
263+
"There is currently no additional '{}' file available. This is fine as it should only be present when rest-api is used.",
264+
propertiesFilePath, e);
273265
}
274266

275267
LOG.debug("saveButton.setOnAction");
276268

277269
saveButton.setOnAction(ae -> {
278270
LOG.info("Save clicked");
279271

280-
RadioButton selectedRadioButton = (RadioButton) toggleGroup.getSelectedToggle();
281-
282-
if (selectedRadioButton == radioApiOff) {
283-
handleApiOff();
284-
} else if (selectedRadioButton == radioApiOn) {
272+
if (activateRestApiCheckBox.isSelected()) {
285273
handleApiOn();
274+
} else {
275+
handleApiOff();
286276
}
287277

288278
if (!OS.isWindows()) {
@@ -334,9 +324,7 @@ private void initialize() {
334324
});
335325

336326
LOG.debug("cancelButton.setOnAction");
337-
cancelButton.setOnAction(ae ->
338-
339-
{
327+
cancelButton.setOnAction(ae -> {
340328
LOG.info("Cancel clicked");
341329
thisStage.close();
342330
});
@@ -356,7 +344,6 @@ private void initialize() {
356344
}
357345

358346
private static void setRegionSvg(Region region, double requiredWidth, double requiredHeight, RESOURCE resource) {
359-
360347
region.setShape(SvgNodeProvider.getSvgNodeWithScale(resource, 1.0, 1.0));
361348
region.setMinSize(requiredWidth, requiredHeight);
362349
region.setPrefSize(requiredWidth, requiredHeight);
@@ -418,17 +405,16 @@ protected void updateItem(final String item, final boolean empty) {
418405
licenseTableView.getColumns().add(nameColumn);
419406
licenseTableView.getColumns().add(licenseColumn);
420407

421-
LOG.debug("hyperlink setonaction");
422408
gitHubHyperlink.setOnAction(ae -> {
423-
LOG.debug("hyperlink clicked");
424409
BrowserHelper.openURL(GITHUB_PAGE);
425410
});
426-
427-
LOG.debug("roportbugbutton setonaction");
428411
reportBugButton.setOnAction(ae -> {
429-
LOG.info("Clicked reportBugButton");
430412
BrowserHelper.openURL(GITHUB_ISSUE_PAGE);
431413
});
414+
swaggerHyperLink.setOnAction(ae -> {
415+
String port = authPort.getText().isEmpty() ? "8080" : authPort.getText();
416+
BrowserHelper.openURL("http://localhost:" + port + "/api/swagger");
417+
});
432418
}
433419

434420
private void initImportButton() {
@@ -444,9 +430,9 @@ private void initImportButton() {
444430
confirmationAlert.setHeaderText("Do you want to Override current Data ?");
445431
confirmationAlert.getDialogPane().setContent(new Label("""
446432
Import previously exported .sql file. This will overwrite the currently used database contents - all current data will be lost!
447-
433+
448434
If you do not have a .sql file yet you need to open the previous version of KeepTime and in the settings dialog press "Export".
449-
435+
450436
You will need to restart the application after this action. If you proceed you need to select the previous exported .sql file.\
451437
"""));
452438
confirmationAlert.showAndWait();
@@ -578,10 +564,6 @@ public void setStage(final Stage thisStage) {
578564
this.thisStage = thisStage;
579565
}
580566

581-
private FXMLLoader createFXMLLoader(final RESOURCE fxmlLayout) {
582-
return new FXMLLoader(Resources.getResource(fxmlLayout));
583-
}
584-
585567
public ObservableList<LicenseTableRow> loadLicenseRows() {
586568
final ObservableList<LicenseTableRow> licenseRows = FXCollections.observableArrayList();
587569
licenseRows.add(new LicenseTableRow("Open Sans", Licenses.APACHEV2));
@@ -620,7 +602,7 @@ private void showLicense(final Licenses license) {
620602

621603
private void handleApiOff() {
622604
Map<String, String> propertiesToUpdate = new HashMap<>();
623-
setWebApplicationType("none");
605+
propertiesToUpdate.put("spring.main.web-application-type", "none");
624606
propertiesToUpdate.put("api", "OFF");
625607
propertyWrite(propertiesToUpdate);
626608
}
@@ -629,53 +611,32 @@ private void handleApiOn() {
629611
String username = authName.getText();
630612
String password = authPassword.getText();
631613

632-
LoginController loginController = new LoginController(username, password);
633-
634-
loginController.createAndSaveUser();
635-
636614
Map<String, String> propertiesToUpdate = new HashMap<>();
637615
propertiesToUpdate.put("spring.main.web-application-type", "");
638616
propertiesToUpdate.put("server.port", authPort.getText());
639617
propertiesToUpdate.put("api", "ON");
618+
propertiesToUpdate.put("spring.security.user.name", username);
619+
propertiesToUpdate.put("spring.security.user.password", password);
640620

641-
propertiesToUpdate.put("spring.security.user.name", "${BASIC_AUTH_USER:" + username + "}");
642-
propertiesToUpdate.put("spring.security.user.password", "${BASIC_AUTH_PASSWORD:" + password + "}");
643621
propertyWrite(propertiesToUpdate);
644622
}
645623

646-
private void setWebApplicationType(String value) {
647-
propertyWrite("spring.main.web-application-type", value);
648-
}
649-
650-
public void propertyWrite(String key, String value) {
624+
private void propertyWrite(Map<String, String> propertiesToUpdate) {
651625
Properties properties = new Properties();
652-
try (InputStream inputStream = getClass().getClassLoader().getResourceAsStream(propertiesFilePath);
653-
FileOutputStream outputStream = new FileOutputStream(propertiesFilePath)) {
654626

627+
try (InputStream inputStream = new FileInputStream(propertiesFilePath)){
655628
properties.load(inputStream);
656-
properties.setProperty(key, value);
657-
properties.store(outputStream, null);
658-
659629
} catch (IOException e) {
660-
e.printStackTrace();
630+
LOG.debug("Could not open '{}' file. This is most likely fine as it was just not needed before and will be created next.", propertiesFilePath, e);
661631
}
662-
}
663-
664-
private void propertyWrite(Map<String, String> propertiesToUpdate) {
665-
Properties properties = new Properties();
666-
try (InputStream inputStream = getClass().getClassLoader().getResourceAsStream(propertiesFilePath);
667-
FileOutputStream outputStream = new FileOutputStream(propertiesFilePath)) {
668-
669-
properties.load(inputStream);
670632

633+
try(FileOutputStream outputStream = new FileOutputStream(propertiesFilePath)) {
671634
for (Map.Entry<String, String> entry : propertiesToUpdate.entrySet()) {
672635
properties.setProperty(entry.getKey(), entry.getValue());
673636
}
674-
675-
properties.store(outputStream, null);
676-
637+
properties.store(outputStream, "REST-API settings");
677638
} catch (IOException e) {
678-
e.printStackTrace();
639+
LOG.error("Error while persisting properties: '{}'.", propertiesToUpdate, e);
679640
}
680641
}
681642

src/main/resources/layouts/settings.fxml

Lines changed: 80 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,10 @@
2525
<?import javafx.scene.control.Hyperlink?>
2626
<?import javafx.scene.control.Label?>
2727
<?import javafx.scene.control.PasswordField?>
28-
<?import javafx.scene.control.RadioButton?>
2928
<?import javafx.scene.control.Tab?>
3029
<?import javafx.scene.control.TabPane?>
3130
<?import javafx.scene.control.TableView?>
3231
<?import javafx.scene.control.TextField?>
33-
<?import javafx.scene.control.ToggleGroup?>
3432
<?import javafx.scene.layout.AnchorPane?>
3533
<?import javafx.scene.layout.HBox?>
3634
<?import javafx.scene.layout.Pane?>
@@ -40,7 +38,7 @@
4038
<?import javafx.scene.text.Font?>
4139
<?import javafx.scene.text.Text?>
4240

43-
<AnchorPane fx:id="settingsRoot" focusTraversable="true" prefHeight="285.0" prefWidth="514.0" style="-fx-background-color: white;" xmlns="http://javafx.com/javafx/21" xmlns:fx="http://javafx.com/fxml/1" fx:controller="de.doubleslash.keeptime.view.SettingsController">
41+
<AnchorPane fx:id="settingsRoot" focusTraversable="true" prefHeight="285.0" prefWidth="514.0" style="-fx-background-color: white;" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1" fx:controller="de.doubleslash.keeptime.view.SettingsController">
4442
<children>
4543
<TabPane layoutX="-50.0" layoutY="3.0" prefHeight="383.0" prefWidth="608.0" rotateGraphic="true" side="LEFT" stylesheets="@../css/settingsv2.css" tabClosingPolicy="UNAVAILABLE">
4644
<tabs>
@@ -372,30 +370,85 @@
372370
<content>
373371
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="420.0" prefWidth="407.0">
374372
<children>
375-
<Label fx:id="labelUsername" layoutX="24.0" layoutY="169.0" text="Username:" />
376-
<Label layoutX="14.0" layoutY="14.0" prefHeight="28.0" prefWidth="279.0" text="Rest API Authentication">
377-
<font>
378-
<Font name="System Bold" size="13.0" />
379-
</font>
380-
</Label>
381-
<Label fx:id="labelPassword" layoutX="24.0" layoutY="219.0" text="Password:" />
382-
<TextField fx:id="authName" layoutX="97.0" layoutY="166.0" prefHeight="26.0" prefWidth="298.0" />
383-
<Label layoutX="24.0" layoutY="70.0" text="Auth" />
384-
<Label fx:id="labelPort" layoutX="26.0" layoutY="124.0" text="Port:" />
385-
<TextField fx:id="authPort" layoutX="97.0" layoutY="120.0" prefHeight="26.0" prefWidth="298.0" promptText="8080" />
386-
<RadioButton fx:id="radioApiOn" layoutX="88.0" layoutY="64.0" mnemonicParsing="false" text="ON">
387-
<toggleGroup>
388-
<ToggleGroup fx:id="authAPI" />
389-
</toggleGroup>
390-
</RadioButton>
391-
<RadioButton fx:id="radioApiOff" layoutX="219.0" layoutY="64.0" mnemonicParsing="false" text="OFF" toggleGroup="$authAPI" />
392-
<PasswordField fx:id="authPassword" layoutX="97.0" layoutY="215.0" prefHeight="26.0" prefWidth="298.0" />
393-
<Label layoutX="24.0" layoutY="261.0" prefHeight="18.0" prefWidth="286.0" text="Warning this is a beta feature" textFill="#bf5d24">
394-
<font>
395-
<Font name="System Bold" size="12.0" />
396-
</font>
397-
</Label>
398-
<Label layoutX="26.0" layoutY="279.0" text="The change will not take effect until the next start " />
373+
<VBox layoutX="14.0" layoutY="14.0" spacing="5.0">
374+
<children>
375+
<VBox styleClass="settingsBorder" stylesheets="@../css/settingsv2.css">
376+
<children>
377+
<Label prefHeight="28.0" prefWidth="279.0" text="REST API Settings">
378+
<font>
379+
<Font name="System Bold" size="13.0" />
380+
</font>
381+
</Label>
382+
</children>
383+
</VBox>
384+
<Group>
385+
<children>
386+
<VBox styleClass="settingsBorder" stylesheets="@../css/settingsv2.css">
387+
<children>
388+
<Label prefHeight="18.0" prefWidth="286.0" text="Warning this is a beta feature" textFill="#bf5d24">
389+
<font>
390+
<Font name="System Bold" size="12.0" />
391+
</font>
392+
</Label>
393+
<Label text="Changes will not take effect until the next start of KeepTime" />
394+
</children>
395+
</VBox>
396+
</children>
397+
</Group>
398+
<Group>
399+
<children>
400+
<VBox styleClass="settingsBorder" stylesheets="@../css/settingsv2.css">
401+
<children>
402+
<CheckBox fx:id="activateRestApiCheckBox" mnemonicParsing="false" text="Activate REST API">
403+
<font>
404+
<Font name="Open Sans Regular" size="12.0" />
405+
</font>
406+
</CheckBox>
407+
<HBox>
408+
<children>
409+
<Label fx:id="labelPort" prefWidth="75.0" text="Port" />
410+
<TextField fx:id="authPort" prefHeight="26.0" prefWidth="298.0" promptText="8080" />
411+
</children>
412+
</HBox>
413+
<HBox>
414+
<children>
415+
<Label fx:id="labelUsername" prefWidth="75.0" text="Username" />
416+
<TextField fx:id="authName" prefHeight="26.0" prefWidth="298.0" />
417+
</children>
418+
</HBox>
419+
<HBox>
420+
<children>
421+
<Label fx:id="labelPassword" prefWidth="75.0" text="Password" />
422+
<PasswordField fx:id="authPassword" prefHeight="26.0" prefWidth="298.0" />
423+
</children>
424+
</HBox>
425+
</children>
426+
</VBox>
427+
</children>
428+
</Group>
429+
<Group>
430+
<children>
431+
<VBox styleClass="settingsBorder" stylesheets="@../css/settingsv2.css">
432+
<children>
433+
<HBox alignment="CENTER_LEFT">
434+
<children>
435+
<Label text="Swagger UI" />
436+
<Hyperlink fx:id="swaggerHyperLink" focusTraversable="false" text="http://localhost:&lt;PORT&gt;/api/swagger" underline="true">
437+
<font>
438+
<Font name="Open Sans Regular" size="14.0" />
439+
</font>
440+
</Hyperlink>
441+
</children>
442+
</HBox>
443+
</children>
444+
</VBox>
445+
</children>
446+
</Group>
447+
</children>
448+
<padding>
449+
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
450+
</padding>
451+
</VBox>
399452
</children></AnchorPane>
400453
</content>
401454
<graphic>

0 commit comments

Comments
 (0)