CCM Admin UI: Edit configuration settings

ccm-docs
Jens Pelzetter 2020-11-07 17:11:55 +01:00
parent b5a48b71f5
commit 0650e1a073
3 changed files with 187 additions and 33 deletions

View File

@ -22,18 +22,24 @@ import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.util.Strings; import org.apache.logging.log4j.util.Strings;
import org.libreccm.core.CoreConstants; import org.libreccm.core.CoreConstants;
import org.libreccm.l10n.LocalizedString;
import org.libreccm.security.AuthorizationRequired; import org.libreccm.security.AuthorizationRequired;
import org.libreccm.security.RequiresPrivilege; import org.libreccm.security.RequiresPrivilege;
import java.lang.reflect.Constructor;
import javax.enterprise.context.RequestScoped; import javax.enterprise.context.RequestScoped;
import javax.inject.Inject; import javax.inject.Inject;
import javax.persistence.EntityManager; import javax.persistence.EntityManager;
import javax.persistence.TypedQuery; import javax.persistence.TypedQuery;
import javax.transaction.Transactional; import javax.transaction.Transactional;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
import java.util.stream.Collectors;
/** /**
* *
@ -163,9 +169,33 @@ public class SettingManager {
settingInfo.setValueType(field.getType().getName()); settingInfo.setValueType(field.getType().getName());
try { try {
final Object conf = configuration.newInstance(); final Constructor<?> constructor = configuration.getConstructor();
settingInfo.setDefaultValue(Objects.toString(field.get(conf))); final Object conf = constructor.newInstance();
} catch (InstantiationException | IllegalAccessException ex) { final Object defaultValueObj = field.get(conf);
final String defaultValue;
if (defaultValueObj instanceof LocalizedString) {
final LocalizedString defaultValueLstr
= (LocalizedString) defaultValueObj;
defaultValue = defaultValueLstr
.getValues()
.entrySet()
.stream()
.map(
entry -> String.format(
"%s: %s",
entry.getKey().toString(), entry.getValue()
)
)
.collect(Collectors.joining(", "));
} else {
defaultValue = Objects.toString(defaultValueObj);
}
settingInfo.setDefaultValue(defaultValue);
} catch (NoSuchMethodException
| InstantiationException
| InvocationTargetException
| IllegalAccessException ex) {
LOGGER.warn(String.format("Failed to create instance of \"%s\" to " LOGGER.warn(String.format("Failed to create instance of \"%s\" to "
+ "get default values.", + "get default values.",
configuration.getName()), configuration.getName()),

View File

@ -20,7 +20,6 @@ package org.libreccm.ui.admin.configuration;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import org.libreccm.configuration.AbstractSetting;
import org.libreccm.configuration.ConfigurationInfo; import org.libreccm.configuration.ConfigurationInfo;
import org.libreccm.configuration.ConfigurationManager; import org.libreccm.configuration.ConfigurationManager;
import org.libreccm.configuration.SettingInfo; import org.libreccm.configuration.SettingInfo;
@ -35,6 +34,7 @@ import org.libreccm.security.RequiresPrivilege;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
@ -163,9 +163,15 @@ public class SettingsController {
.getClass() .getClass()
.getDeclaredField(settingInfo.getName()); .getDeclaredField(settingInfo.getName());
field.setAccessible(true); field.setAccessible(true);
if (field.get(configuration) instanceof LocalizedString) { final Object valueObj = field.get(configuration);
final LocalizedString localizedStr = (LocalizedString) field if (valueObj instanceof List) {
.get(configuration); @SuppressWarnings("unchecked")
final List<String> list = (List<String>) valueObj;
value = list
.stream()
.collect(Collectors.joining("\n"));
} else if (valueObj instanceof LocalizedString) {
final LocalizedString localizedStr = (LocalizedString) valueObj;
value = localizedStr value = localizedStr
.getValues() .getValues()
.entrySet() .entrySet()
@ -177,9 +183,15 @@ public class SettingsController {
) )
) )
.sorted() .sorted()
.collect(Collectors.joining(", ")); .collect(Collectors.joining("\n"));
} else if (valueObj instanceof Set) {
@SuppressWarnings("unchecked")
final Set<String> set = (Set<String>) valueObj;
value = set
.stream()
.collect(Collectors.joining("\n"));
} else { } else {
value = Objects.toString(field.get(configuration)); value = Objects.toString(valueObj);
} }
} catch (NoSuchFieldException | IllegalAccessException | SecurityException ex) { } catch (NoSuchFieldException | IllegalAccessException | SecurityException ex) {
LOGGER.error( LOGGER.error(
@ -286,7 +298,7 @@ public class SettingsController {
valueParam valueParam
); );
} else if (valueType.equals(Set.class.getName())) { } else if (valueType.equals(Set.class.getName())) {
return updateStringListSetting( return updateStringSetSetting(
configurationClassName, configurationClassName,
confClass, confClass,
conf, conf,
@ -403,7 +415,7 @@ public class SettingsController {
continue; continue;
} }
final Locale locale = new Locale(tokens[0]); final Locale locale = new Locale(tokens[0]);
final String localeValue = tokens[1]; final String localeValue = tokens[1].trim();
value.addValue(locale, localeValue); value.addValue(locale, localeValue);
} }
return updateSetting( return updateSetting(
@ -452,9 +464,33 @@ public class SettingsController {
final String settingName, final String settingName,
final String valueType, final String valueType,
final String valueParam final String valueParam
) {
final String[] tokens = valueParam.split("\n");
final List<String> value = Arrays
.asList(tokens)
.stream()
.map(String::trim)
.collect(Collectors.toList());
return updateSetting(
configurationClassName,
configurationClass,
configuration,
settingName,
valueType,
value
);
}
private String updateStringSetSetting(
final String configurationClassName,
final Class<?> configurationClass,
final Object configuration,
final String settingName,
final String valueType,
final String valueParam
) { ) {
final String[] tokens = valueParam.split(","); final String[] tokens = valueParam.split(",");
final List<String> value = Arrays.asList(tokens); final Set<String> value = new HashSet<>(Arrays.asList(tokens));
return updateSetting( return updateSetting(
configurationClassName, configurationClassName,
configurationClass, configurationClass,

View File

@ -57,7 +57,7 @@
</c:when> </c:when>
<c:otherwise> <c:otherwise>
<strong> <strong>
#{setting.value} <pre>#{setting.value}</pre>
</strong> </strong>
</c:otherwise> </c:otherwise>
</c:choose> </c:choose>
@ -148,7 +148,22 @@
<div class="modal-body"> <div class="modal-body">
<c:choose> <c:choose>
<c:when test="#{setting.valueType.equals(BigDecimalClassName)}"> <c:when test="#{setting.valueType.equals(BigDecimalClassName)}">
<pre>BigDecimal</pre> <div class="form-group">
<label for="#{setting.name}-setting-value">
#{AdminMessages['configuration.settings.setting.dialog.value.label']}
</label>
<input aria-describedby="#{setting.name}-setting-value-help"
class="form-control"
id="#{setting.name}-setting-value"
name="settingValue"
step="0.01"
type="number"
value="#{setting.value}" />
<small class="form-text text-muted"
id="#{setting.name}-setting-value-help">
#{setting.description}
</small>
</div>
</c:when> </c:when>
<c:when test="#{setting.valueType.equals(BooleanClassName) or setting.valueType.equals('boolean')}"> <c:when test="#{setting.valueType.equals(BooleanClassName) or setting.valueType.equals('boolean')}">
<div class="form-group form-check"> <div class="form-group form-check">
@ -169,11 +184,28 @@
</div> </div>
</c:when> </c:when>
<c:when test="#{setting.valueType.equals(DoubleClassName) or setting.valueType.equals('double')}"> <c:when test="#{setting.valueType.equals(DoubleClassName) or setting.valueType.equals('double')}">
<pre>double</pre> <div class="form-group">
<label for="#{setting.name}-setting-value">
#{AdminMessages['configuration.settings.setting.dialog.value.label']}
</label>
<input aria-describedby="#{setting.name}-setting-value-help"
class="form-control"
id="#{setting.name}-setting-value"
max="#{DoubleMaxValue}"
min="#{DoubleMinValue}"
name="settingValue"
step="0.01"
type="number"
value="#{setting.value}" />
<small class="form-text text-muted"
id="#{setting.name}-setting-value-help">
#{setting.description}
</small>
</div>
</c:when> </c:when>
<c:when test="#{setting.valueType.equals(IntegerClassName) or setting.valueType.equals('int')}"> <c:when test="#{setting.valueType.equals(IntegerClassName) or setting.valueType.equals('int')}">
<div class="form-group"> <div class="form-group">
<label for="#{setting-name}-setting-value"> <label for="#{setting.name}-setting-value">
#{AdminMessages['configuration.settings.setting.dialog.value.label']} #{AdminMessages['configuration.settings.setting.dialog.value.label']}
</label> </label>
<input aria-describedby="#{setting.name}-setting-value-help" <input aria-describedby="#{setting.name}-setting-value-help"
@ -193,41 +225,97 @@
</c:when> </c:when>
<c:when test="#{setting.valueType.equals(ListClassName)}"> <c:when test="#{setting.valueType.equals(ListClassName)}">
<pre>List</pre> <div class="form-group">
<label for="#{setting.name}-setting-value">
#{AdminMessages['configuration.settings.setting.dialog.value.label']}
</label>
<textarea aria-describedby="#{setting.name}-setting-value-help"
class="form-control"
cols="80"
id="#{setting.name}-setting-value"
name="settingValue"
rows="10">#{setting.value}</textarea>
<small class="form-text text-muted"
id="#{setting.name}-setting-value-help">
#{setting.description}
</small>
</div>
</c:when> </c:when>
<c:when test="#{setting.valueType.equals(LocalizedStringClassName)}"> <c:when test="#{setting.valueType.equals(LocalizedStringClassName)}">
<pre>LocalizedString</pre> <div class="form-group">
<label for="#{setting.name}-setting-value">
#{AdminMessages['configuration.settings.setting.dialog.value.label']}
</label>
<textarea aria-describedby="#{setting.name}-setting-value-help"
class="form-control"
cols="80"
id="#{setting.name}-setting-value"
name="settingValue"
rows="10">#{setting.value}</textarea>
<small class="form-text text-muted"
id="#{setting.name}-setting-value-help">
#{setting.description}
</small>
</div>
</c:when> </c:when>
<c:when test="#{setting.valueType.equals(LongClassName) or setting.valueType.equals('long')}"> <c:when test="#{setting.valueType.equals(LongClassName) or setting.valueType.equals('long')}">
<div class="form-group"> <div class="form-group">
<label for="#{setting-name}-setting-value"> <label for="#{setting.name}-setting-value">
#{AdminMessages['configuration.settings.setting.dialog.value.label']}
</label>
<input aria-describedby="#{setting.name}-setting-value-help"
class="form-control"
id="#{setting.name}-setting-value"
max="#{LongMaxValue}"
min="#{LongMinValue}"
name="settingValue"
step="1"
type="number"
value="#{setting.value}" />
<small class="form-text text-muted"
id="#{setting.name}-setting-value-help">
#{setting.description}
</small>
</div>
</c:when>
<c:when test="#{setting.valueType.equals(SetClassName)}">
<div class="form-group">
<label for="#{setting.name}-setting-value">
#{AdminMessages['configuration.settings.setting.dialog.value.label']}
</label>
<textarea aria-describedby="#{setting.name}-setting-value-help"
class="form-control"
cols="80"
id="#{setting.name}-setting-value"
name="settingValue"
rows="10">#{setting.value}</textarea>
<small class="form-text text-muted"
id="#{setting.name}-setting-value-help">
#{setting.description}
</small>
</div>
</c:when>
<c:when test="#{setting.valueType.equals(StringClassName)}">
<div class="form-group">
<label for="#{setting.name}-setting-value">
#{AdminMessages['configuration.settings.setting.dialog.value.label']} #{AdminMessages['configuration.settings.setting.dialog.value.label']}
</label> </label>
<input aria-describedby="#{setting.name}-setting-value-help" <input aria-describedby="#{setting.name}-setting-value-help"
class="form-control" class="form-control"
id="#{setting.name}-setting-value" id="#{setting.name}-setting-value"
name="settingValue" name="settingValue"
step="1" type="text"
type="number"
value="#{setting.value}" /> value="#{setting.value}" />
<small class="form-text text-muted"
id="#{setting.name}-setting-value-help">
#{setting.description}
</small>
</div> </div>
</c:when> </c:when>
<c:when test="#{setting.valueType.equals(SetClassName)}">
<pre>Set</pre>
</c:when>
<c:when test="#{setting.valueType.equals(StringClassName)}">
<pre>String</pre>
</c:when>
<c:otherwise> <c:otherwise>
<p> <p>
#{AdminMessages.getMessage('configuration.settings.setting.dialog.unsupported_type', [setting.valueType])} #{AdminMessages.getMessage('configuration.settings.setting.dialog.unsupported_type', [setting.valueType])}
</p> </p>
<pre>
setting.valueType: #{setting.valueType}
Boolean: #{BooleanClassName}
LocalizedString: #{LocalizedStringClassName}
</pre>
</c:otherwise> </c:otherwise>
</c:choose> </c:choose>
</div> </div>