diff --git a/ccm-core/src/main/java/org/libreccm/ui/admin/configuration/SettingsController.java b/ccm-core/src/main/java/org/libreccm/ui/admin/configuration/SettingsController.java index bf7008af2..7c5a5a879 100644 --- a/ccm-core/src/main/java/org/libreccm/ui/admin/configuration/SettingsController.java +++ b/ccm-core/src/main/java/org/libreccm/ui/admin/configuration/SettingsController.java @@ -18,6 +18,8 @@ */ package org.libreccm.ui.admin.configuration; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.libreccm.configuration.AbstractSetting; import org.libreccm.configuration.ConfigurationInfo; import org.libreccm.configuration.ConfigurationManager; @@ -30,6 +32,7 @@ import org.libreccm.l10n.LocalizedTextsUtil; import org.libreccm.security.AuthorizationRequired; import org.libreccm.security.RequiresPrivilege; +import java.lang.reflect.Field; import java.math.BigDecimal; import java.util.Arrays; import java.util.List; @@ -43,6 +46,7 @@ import javax.enterprise.context.RequestScoped; import javax.inject.Inject; import javax.mvc.Controller; import javax.mvc.Models; +import javax.transaction.Transactional; import javax.ws.rs.FormParam; import javax.ws.rs.GET; import javax.ws.rs.POST; @@ -58,6 +62,10 @@ import javax.ws.rs.PathParam; @Path("/configuration/{configurationClass}") public class SettingsController { + private static final Logger LOGGER = LogManager.getLogger( + SettingsController.class + ); + @Inject private ConfigurationManager confManager; @@ -72,6 +80,7 @@ public class SettingsController { @GET @Path("/") + @Transactional(Transactional.TxType.REQUIRED) @AuthorizationRequired @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN) public String showSettings( @@ -100,19 +109,22 @@ public class SettingsController { textUtil.getText(confInfo.getDescKey()) ); + final Object configuration = confManager.findConfiguration(confClass); + final List settings = confInfo .getSettings() .entrySet() .stream() .map(Map.Entry::getValue) - .map(this::buildSettingsTableEntry) + .map(settingInfo -> buildSettingsTableEntry(settingInfo, + configuration)) .sorted() .collect(Collectors.toList()); models.put("configurationClass", configurationClass); - + models.put("settings", settings); - + models.put("BigDecimalClassName", BigDecimal.class.getName()); models.put("BooleanClassName", Boolean.class.getName()); models.put("DoubleClassName", Double.class.getName()); @@ -123,20 +135,64 @@ public class SettingsController { models.put("LocalizedStringClassName", LocalizedString.class.getName()); models.put("SetClassName", Set.class.getName()); models.put("StringClassName", String.class.getName()); + + models.put("IntegerMaxValue", Integer.toString(Integer.MAX_VALUE)); + models.put("IntegerMinValue", Integer.toString(Integer.MIN_VALUE)); + models.put("LongMaxValue", Long.toString(Long.MAX_VALUE)); + models.put("LongMinValue", Long.toString(Long.MIN_VALUE)); + models.put("DoubleMaxValue", Double.toString(Double.MAX_VALUE)); + models.put("DoubleMinValue", Double.toString(Double.MIN_VALUE)); return "org/libreccm/ui/admin/configuration/settings.xhtml"; } + @Transactional(Transactional.TxType.REQUIRED) private SettingsTableEntry buildSettingsTableEntry( - final SettingInfo settingInfo + final SettingInfo settingInfo, + final Object configuration ) { Objects.requireNonNull(settingInfo); + Objects.requireNonNull(configuration); final LocalizedTextsUtil textsUtil = globalizationHelper .getLocalizedTextsUtil(settingInfo.getDescBundle()); + String value; + try { + final Field field = configuration + .getClass() + .getDeclaredField(settingInfo.getName()); + field.setAccessible(true); + if (field.get(configuration) instanceof LocalizedString) { + final LocalizedString localizedStr = (LocalizedString) field + .get(configuration); + value = localizedStr + .getValues() + .entrySet() + .stream() + .map( + entry -> String.format( + "%s: %s", + entry.getKey().toString(), entry.getValue() + ) + ) + .sorted() + .collect(Collectors.joining(", ")); + } else { + value = Objects.toString(field.get(configuration)); + } + } catch (NoSuchFieldException | IllegalAccessException | SecurityException ex) { + LOGGER.error( + "Failed to get value for field {} of configuration {}.", + settingInfo.getName(), + configuration.getClass().getName() + ); + LOGGER.error(ex); + value = "?err?"; + } final SettingsTableEntry entry = new SettingsTableEntry(); entry.setName(settingInfo.getName()); + entry.setValue(value); entry.setValueType(settingInfo.getValueType()); entry.setDefaultValue(settingInfo.getDefaultValue()); entry.setLabel(textsUtil.getText(settingInfo.getLabelKey())); @@ -147,12 +203,16 @@ public class SettingsController { @POST @Path("/{settingName}") + @Transactional(Transactional.TxType.REQUIRED) @AuthorizationRequired @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN) public String updateSettingValue( - @PathParam("configurationClass") final String configurationClassName, - @PathParam("settingName") final String settingName, - @FormParam("settingValue") final String valueParam + @PathParam("configurationClass") + final String configurationClassName, + @PathParam("settingName") + final String settingName, + @FormParam("settingValue") + final String valueParam ) { final Class confClass; try { @@ -161,6 +221,7 @@ public class SettingsController { models.put("configurationClass", configurationClassName); return "org/libreccm/ui/admin/configuration/configuration-class-not-found.xhtml"; } + final Object conf = confManager.findConfiguration(confClass); final SettingInfo settingInfo = settingManager.getSettingInfo( confClass, settingName ); @@ -168,38 +229,79 @@ public class SettingsController { final String valueType = settingInfo.getValueType(); if (valueType.equals(BigDecimal.class.getName())) { return updateBigDecimalSetting( - configurationClassName, settingName, valueType, valueParam + configurationClassName, + confClass, + conf, + settingName, + valueType, + valueParam ); } else if (valueType.equals(Boolean.class.getName()) || valueType.equals("boolean")) { + final boolean value = valueParam != null; return updateBooleanSetting( - configurationClassName, settingName, valueType, valueParam + configurationClassName, + confClass, + conf, + settingName, + valueType, + value ); } else if (valueType.equals(Double.class.getName()) || valueType.equals("double")) { return updateDoubleSetting( - configurationClassName, settingName, valueType, valueParam + configurationClassName, + confClass, + conf, + settingName, + valueType, + valueParam ); } else if (valueType.equals(LocalizedString.class.getName())) { return updateLocalizedStringSetting( - configurationClassName, settingName, valueType, valueParam + configurationClassName, + confClass, + conf, + settingName, + valueType, + valueParam ); } else if (valueType.equals(Long.class.getName()) || valueType.equals("long")) { return updateLongSetting( - configurationClassName, settingName, valueType, valueParam + configurationClassName, + confClass, + conf, + settingName, + valueType, + valueParam ); } else if (valueType.equals(List.class.getName())) { return updateStringListSetting( - configurationClassName, settingName, valueType, valueParam + configurationClassName, + confClass, + conf, + settingName, + valueType, + valueParam ); } else if (valueType.equals(Set.class.getName())) { return updateStringListSetting( - configurationClassName, settingName, valueType, valueParam + configurationClassName, + confClass, + conf, + settingName, + valueType, + valueParam ); } else if (valueType.equals(String.class.getName())) { return updateStringSetting( - configurationClassName, settingName, valueType, valueParam + configurationClassName, + confClass, + conf, + settingName, + valueType, + valueParam ); } else { models.put("configurationClass", configurationClassName); @@ -211,6 +313,8 @@ public class SettingsController { private String updateBigDecimalSetting( final String configurationClassName, + final Class configurationClass, + final Object configuration, final String settingName, final String valueType, final String valueParam @@ -226,54 +330,38 @@ public class SettingsController { valueParam ); } - - final AbstractSetting setting = settingManager - .findSetting( - configurationClassName, settingName, BigDecimal.class - ); - - if (setting == null) { - return buildSettingNotFoundErrorTarget( - configurationClassName, - settingName, - valueType - ); - } else { - setting.setValue(value); - settingManager.saveSetting(setting); - return buildRedirectAfterUpdateSettingTarget( - configurationClassName - ); - } + return updateSetting( + configurationClassName, + configurationClass, + configuration, + settingName, + valueType, + value + ); } private String updateBooleanSetting( final String configurationClassName, + final Class configurationClass, + final Object configuration, final String settingName, final String valueType, - final String valueParam + final boolean value ) { - final Boolean value = Boolean.valueOf(valueParam); - - final AbstractSetting setting = settingManager.findSetting( - configurationClassName, settingName, Boolean.class + return updateSetting( + configurationClassName, + configurationClass, + configuration, + settingName, + valueType, + value ); - - if (setting == null) { - return buildSettingNotFoundErrorTarget( - configurationClassName, settingName, valueType - ); - } else { - setting.setValue(value); - settingManager.saveSetting(setting); - return buildRedirectAfterUpdateSettingTarget( - configurationClassName - ); - } } private String updateDoubleSetting( final String configurationClassName, + final Class configurationClass, + final Object configuration, final String settingName, final String valueType, final String valueParam @@ -289,26 +377,20 @@ public class SettingsController { valueParam ); } - - final AbstractSetting setting = settingManager.findSetting( - configurationClassName, settingName, Double.class + return updateSetting( + configurationClassName, + configurationClass, + configuration, + settingName, + valueType, + value ); - - if (setting == null) { - return buildSettingNotFoundErrorTarget( - configurationClassName, settingName, valueType - ); - } else { - setting.setValue(value); - settingManager.saveSetting(setting); - return buildRedirectAfterUpdateSettingTarget( - configurationClassName - ); - } } private String updateLocalizedStringSetting( final String configurationClassName, + final Class configurationClass, + final Object configuration, final String settingName, final String valueType, final String valueParam @@ -324,27 +406,20 @@ public class SettingsController { final String localeValue = tokens[1]; value.addValue(locale, localeValue); } - - final AbstractSetting setting = settingManager - .findSetting( - configurationClassName, settingName, LocalizedString.class - ); - - if (setting == null) { - return buildSettingNotFoundErrorTarget( - configurationClassName, settingName, valueType - ); - } else { - setting.setValue(value); - settingManager.saveSetting(setting); - return buildRedirectAfterUpdateSettingTarget( - configurationClassName - ); - } + return updateSetting( + configurationClassName, + configurationClass, + configuration, + settingName, + valueType, + value + ); } private String updateLongSetting( final String configurationClassName, + final Class configurationClass, + final Object configuration, final String settingName, final String valueType, final String valueParam @@ -360,70 +435,82 @@ public class SettingsController { valueParam ); } - - final AbstractSetting setting = settingManager.findSetting( - configurationClassName, settingName, Long.class + return updateSetting( + configurationClassName, + configurationClass, + configuration, + settingName, + valueType, + value ); - - if (setting == null) { - return buildSettingNotFoundErrorTarget( - configurationClassName, settingName, valueType - ); - } else { - setting.setValue(value); - settingManager.saveSetting(setting); - return buildRedirectAfterUpdateSettingTarget( - configurationClassName - ); - } } private String updateStringListSetting( final String configurationClassName, + final Class configurationClass, + final Object configuration, final String settingName, final String valueType, final String valueParam ) { final String[] tokens = valueParam.split(","); final List value = Arrays.asList(tokens); - - final AbstractSetting setting = settingManager.findSetting( - configurationClassName, settingName, List.class + return updateSetting( + configurationClassName, + configurationClass, + configuration, + settingName, + valueType, + value ); - - if (setting == null) { - return buildSettingNotFoundErrorTarget( - configurationClassName, settingName, valueType - ); - } else { - setting.setValue(value); - settingManager.saveSetting(setting); - return buildRedirectAfterUpdateSettingTarget( - configurationClassName - ); - } } private String updateStringSetting( final String configurationClassName, + final Class configurationClass, + final Object configuration, final String settingName, final String valueType, - final String valueParam + final String value ) { - final AbstractSetting setting = settingManager.findSetting( - configurationClassName, settingName, String.class + return updateSetting( + configurationClassName, + configurationClass, + configuration, + settingName, + valueType, + value ); + } - if (setting == null) { - return buildSettingNotFoundErrorTarget( - configurationClassName, settingName, valueType + private String updateSetting( + final String configurationClassName, + final Class configurationClass, + final Object configuration, + final String settingName, + final String valueType, + final Object value + ) { + try { + final Field field = configurationClass.getDeclaredField( + settingName ); - } else { - setting.setValue(valueParam); - settingManager.saveSetting(setting); + field.setAccessible(true); + field.set(configuration, value); + confManager.saveConfiguration(configuration); return buildRedirectAfterUpdateSettingTarget( configurationClassName ); + } catch (NoSuchFieldException ex) { + return buildSettingNotFoundErrorTarget( + configurationClassName, + settingName, + valueType); + } catch (SecurityException | IllegalAccessException ex) { + LOGGER.error("Failed to update setting.", ex); + models.put("configurationClass", configurationClassName); + models.put("settingName", settingName); + return "org/libreccm/ui/admin/configuration/failed-to-update-setting.xhtml"; } } diff --git a/ccm-core/src/main/resources/WEB-INF/views/org/libreccm/ui/admin/configuration/configuration-class-not-found.xhtml b/ccm-core/src/main/resources/WEB-INF/views/org/libreccm/ui/admin/configuration/configuration-class-not-found.xhtml index 2ddf557dc..3beb3feca 100644 --- a/ccm-core/src/main/resources/WEB-INF/views/org/libreccm/ui/admin/configuration/configuration-class-not-found.xhtml +++ b/ccm-core/src/main/resources/WEB-INF/views/org/libreccm/ui/admin/configuration/configuration-class-not-found.xhtml @@ -16,7 +16,7 @@ - + diff --git a/ccm-core/src/main/resources/WEB-INF/views/org/libreccm/ui/admin/configuration/failed-to-update-setting.xhtml b/ccm-core/src/main/resources/WEB-INF/views/org/libreccm/ui/admin/configuration/failed-to-update-setting.xhtml new file mode 100644 index 000000000..fbceb64aa --- /dev/null +++ b/ccm-core/src/main/resources/WEB-INF/views/org/libreccm/ui/admin/configuration/failed-to-update-setting.xhtml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ccm-core/src/main/resources/WEB-INF/views/org/libreccm/ui/admin/configuration/invalid-setting-value.xhtml b/ccm-core/src/main/resources/WEB-INF/views/org/libreccm/ui/admin/configuration/invalid-setting-value.xhtml index 9488ff48d..797eb5374 100644 --- a/ccm-core/src/main/resources/WEB-INF/views/org/libreccm/ui/admin/configuration/invalid-setting-value.xhtml +++ b/ccm-core/src/main/resources/WEB-INF/views/org/libreccm/ui/admin/configuration/invalid-setting-value.xhtml @@ -16,7 +16,7 @@ - + diff --git a/ccm-core/src/main/resources/WEB-INF/views/org/libreccm/ui/admin/configuration/setting-not-found.xhtml b/ccm-core/src/main/resources/WEB-INF/views/org/libreccm/ui/admin/configuration/setting-not-found.xhtml index a686c94f9..ee11042a2 100644 --- a/ccm-core/src/main/resources/WEB-INF/views/org/libreccm/ui/admin/configuration/setting-not-found.xhtml +++ b/ccm-core/src/main/resources/WEB-INF/views/org/libreccm/ui/admin/configuration/setting-not-found.xhtml @@ -16,7 +16,7 @@ - + diff --git a/ccm-core/src/main/resources/WEB-INF/views/org/libreccm/ui/admin/configuration/settings.xhtml b/ccm-core/src/main/resources/WEB-INF/views/org/libreccm/ui/admin/configuration/settings.xhtml index 6687c1488..5c244aefa 100644 --- a/ccm-core/src/main/resources/WEB-INF/views/org/libreccm/ui/admin/configuration/settings.xhtml +++ b/ccm-core/src/main/resources/WEB-INF/views/org/libreccm/ui/admin/configuration/settings.xhtml @@ -150,9 +150,10 @@
BigDecimal
- +
- -
Double
+ +
double
- -
Integer
-
- -
int
+ +
+ + + + #{setting.description} + +
+
List
@@ -182,6 +198,21 @@
LocalizedString
+ +
+ + + +
+
Set
diff --git a/ccm-core/src/main/resources/WEB-INF/views/org/libreccm/ui/admin/configuration/unsupported-setting-type.xhtml b/ccm-core/src/main/resources/WEB-INF/views/org/libreccm/ui/admin/configuration/unsupported-setting-type.xhtml index e59cb77ba..a75b13749 100644 --- a/ccm-core/src/main/resources/WEB-INF/views/org/libreccm/ui/admin/configuration/unsupported-setting-type.xhtml +++ b/ccm-core/src/main/resources/WEB-INF/views/org/libreccm/ui/admin/configuration/unsupported-setting-type.xhtml @@ -16,7 +16,7 @@
- + diff --git a/ccm-core/src/main/resources/org/libreccm/ui/AdminBundle.properties b/ccm-core/src/main/resources/org/libreccm/ui/AdminBundle.properties index 151739c4b..fcb595bc5 100644 --- a/ccm-core/src/main/resources/org/libreccm/ui/AdminBundle.properties +++ b/ccm-core/src/main/resources/org/libreccm/ui/AdminBundle.properties @@ -234,3 +234,5 @@ configuration.setting.invalid_type.message=Setting {1} of configuration class {0 configuration.setting.not_found.title=Setting not found configuration.setting.not_found.message=Setting {1} of type {2} not found in configuration class {0} configuration.settings.setting.dialog.value.label=Value +configuration.setting.failed_to_update.title=Failed to update setting +configuration.setting.failed_to_update.message=Failed to update setting {1} of configuration {0}. diff --git a/ccm-core/src/main/resources/org/libreccm/ui/AdminBundle_de.properties b/ccm-core/src/main/resources/org/libreccm/ui/AdminBundle_de.properties index c23c2fb8c..80a2c5a45 100644 --- a/ccm-core/src/main/resources/org/libreccm/ui/AdminBundle_de.properties +++ b/ccm-core/src/main/resources/org/libreccm/ui/AdminBundle_de.properties @@ -232,5 +232,7 @@ configuration.setting.type_unsupported.message=Einstellung {1} aus Konfiguration configuration.setting.invalid_type.title=Invalid type of value configuration.setting.invalid_type.message=Einstellung {1} der Konfigurations-Klasse {0} ist vom Typ {2}, der angegebene Wert {3} kann aber nicht in diesen Typ konvertiert werden configuration.setting.not_found.title=Einstellung nicht gefunden -configuration.setting.not_found.message=Keine Einstellung {1} vom Typ {3} in Konfiguration {0} gefunden +configuration.setting.not_found.message=Keine Einstellung {1} vom Typ {2} in Konfiguration {0} gefunden configuration.settings.setting.dialog.value.label=Wert +configuration.setting.failed_to_update.title=Aktualisieren der Einstellung fehlgeschlagen +configuration.setting.failed_to_update.message=Aktualisieren der Einstellung {1} in Konfiguration {0} fehlgeschlagen.