diff --git a/ccm-core/src/main/java/org/libreccm/api/admin/AdminApi.java b/ccm-core/src/main/java/org/libreccm/api/admin/AdminApi.java
index e954ec9f7..2c925a9ab 100644
--- a/ccm-core/src/main/java/org/libreccm/api/admin/AdminApi.java
+++ b/ccm-core/src/main/java/org/libreccm/api/admin/AdminApi.java
@@ -20,6 +20,7 @@ import org.libreccm.api.DefaultResponseHeaders;
import org.libreccm.api.PreflightRequestFilter;
import org.libreccm.api.admin.categorization.CategoriesApi;
import org.libreccm.api.admin.categorization.DomainsApi;
+import org.libreccm.configuration.Configuration;
/**
*
@@ -40,6 +41,9 @@ public class AdminApi extends Application {
classes.add(DomainsApi.class);
classes.add(CategoriesApi.class);
+ // Configuration API
+ classes.add(Configuration.class);
+
// Security API
classes.add(GroupsApi.class);
classes.add(RolesApi.class);
diff --git a/ccm-core/src/main/java/org/libreccm/api/admin/configuration/BigDecimalConverter.java b/ccm-core/src/main/java/org/libreccm/api/admin/configuration/BigDecimalConverter.java
new file mode 100644
index 000000000..2f6aa10f9
--- /dev/null
+++ b/ccm-core/src/main/java/org/libreccm/api/admin/configuration/BigDecimalConverter.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2020 LibreCCM Foundation.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+package org.libreccm.api.admin.configuration;
+
+import java.math.BigDecimal;
+
+import javax.json.JsonNumber;
+import javax.json.JsonValue;
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.Response;
+
+/**
+ *
+ * @author Jens Pelzetter
+ */
+class BigDecimalConverter implements SettingValueConverter {
+
+ @Override
+ public BigDecimal convertSettingValue(final JsonValue value) {
+ if (value.getValueType() == JsonValue.ValueType.NUMBER) {
+ return ((JsonNumber) value).bigDecimalValue();
+ } else {
+ throw new WebApplicationException(
+ "The provided value is not a number.",
+ Response.Status.BAD_REQUEST
+ );
+ }
+ }
+
+}
diff --git a/ccm-core/src/main/java/org/libreccm/api/admin/configuration/BooleanConverter.java b/ccm-core/src/main/java/org/libreccm/api/admin/configuration/BooleanConverter.java
new file mode 100644
index 000000000..f103cace7
--- /dev/null
+++ b/ccm-core/src/main/java/org/libreccm/api/admin/configuration/BooleanConverter.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2020 LibreCCM Foundation.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+package org.libreccm.api.admin.configuration;
+
+import javax.json.JsonValue;
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.Response;
+
+/**
+ *
+ * @author Jens Pelzetter
+ */
+class BooleanConverter implements SettingValueConverter {
+
+ @Override
+ public Boolean convertSettingValue(final JsonValue value) {
+ switch(value.getValueType()) {
+ case FALSE:
+ return false;
+ case TRUE:
+ return true;
+ default:
+ throw new WebApplicationException(
+ "The provided value is not a boolean.",
+ Response.Status.BAD_REQUEST
+ );
+ }
+ }
+}
diff --git a/ccm-core/src/main/java/org/libreccm/api/admin/configuration/ConfigurationApi.java b/ccm-core/src/main/java/org/libreccm/api/admin/configuration/ConfigurationApi.java
new file mode 100644
index 000000000..2289e1a5c
--- /dev/null
+++ b/ccm-core/src/main/java/org/libreccm/api/admin/configuration/ConfigurationApi.java
@@ -0,0 +1,296 @@
+/*
+ * Copyright (C) 2020 LibreCCM Foundation.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+package org.libreccm.api.admin.configuration;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.libreccm.configuration.ConfigurationInfo;
+import org.libreccm.configuration.ConfigurationManager;
+import org.libreccm.configuration.SettingInfo;
+import org.libreccm.l10n.LocalizedString;
+
+import java.lang.reflect.Field;
+import java.math.BigDecimal;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.stream.Collectors;
+
+import javax.enterprise.context.RequestScoped;
+import javax.inject.Inject;
+import javax.json.JsonValue;
+import javax.ws.rs.GET;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.Response;
+
+/**
+ *
+ * @author Jens Pelzetter
+ */
+@RequestScoped
+@Path("/configuration")
+public class ConfigurationApi {
+
+ private static final Logger LOGGER = LogManager.getLogger(
+ ConfigurationApi.class
+ );
+
+ @Inject
+ private ConfigurationManager confManager;
+
+ private final Map> converters;
+
+ public ConfigurationApi() {
+ converters = new HashMap<>();
+ converters.put(BigDecimal.class.getName(), new BigDecimalConverter());
+ converters.put(Boolean.class.getName(), new BooleanConverter());
+ converters.put(Double.class.getName(), new DoubleConverter());
+ converters.put(EnumConverter.class.getName(), new EnumConverter());
+ converters.put(
+ LocalizedString.class.getName(), new LocalizedStringConverter()
+ );
+ converters.put(Long.class.getName(), new LongConverter());
+ converters.put(String.class.getName(), new StringConverter());
+ converters.put(List.class.getName(), new StringListConverter());
+ }
+
+ @GET
+ @Path("/")
+ public List getConfigurations() {
+ return confManager
+ .findAllConfigurations()
+ .stream()
+ .map(confManager::getConfigurationInfo)
+ .collect(Collectors.toList());
+ }
+
+ @GET
+ @Path("/{confName}")
+ public ConfigurationInfo getConfiguration(
+ @PathParam("confName") final String confName
+ ) {
+ final Class> clazz;
+ try {
+ clazz = Class.forName(confName);
+ } catch (ClassNotFoundException ex) {
+ throw new WebApplicationException(
+ String.format("No configuration %s available.", confName),
+ Response.Status.NOT_FOUND
+ );
+ }
+ try {
+ return confManager.getConfigurationInfo(clazz);
+ } catch (IllegalArgumentException ex) {
+ // We don't expose that we found a class for that name, but that
+ // it is not an Configuration class.
+ throw new WebApplicationException(
+ String.format("No configuration %s available.", confName),
+ Response.Status.NOT_FOUND
+ );
+ }
+ }
+
+ @GET
+ @Path("/{confName}/{setting}")
+ @SuppressWarnings("unchecked")
+ public Object getSetting(
+ @PathParam("confName") final String confName,
+ @PathParam("setting") final String setting
+ ) {
+ final Class> clazz;
+ try {
+ clazz = Class.forName(confName);
+ } catch (ClassNotFoundException ex) {
+ throw new WebApplicationException(
+ String.format("No configuration %s available.", confName),
+ Response.Status.NOT_FOUND
+ );
+ }
+
+ final Object conf;
+ try {
+ conf = confManager.findConfiguration(clazz);
+ } catch (IllegalArgumentException ex) {
+ // We don't expose that we found a class for that name, but that
+ // it is not an Configuration class.
+ throw new WebApplicationException(
+ String.format("No configuration %s available.", confName),
+ Response.Status.NOT_FOUND
+ );
+ }
+
+ final Field field;
+ try {
+ field = clazz.getDeclaredField(setting);
+ } catch (NoSuchFieldException ex) {
+ throw new WebApplicationException(
+ String.format(
+ "The configuration \"%s\" has not setting \"%s\".",
+ confName,
+ setting
+ ),
+ Response.Status.NOT_FOUND
+ );
+ }
+
+ field.setAccessible(true);
+
+ try {
+ return field.get(conf);
+ } catch (IllegalAccessException | IllegalArgumentException ex) {
+ throw new WebApplicationException(
+ String.format(
+ "Failed to retrieve setting \"%s\" "
+ + "from configuration \"%s\"",
+ setting,
+ confName
+ )
+ );
+ }
+ }
+
+ @PUT
+ @Path("/{confName}/{setting}")
+ public Response updateSetting(
+ @PathParam("confName") final String confName,
+ @PathParam("setting") final String setting,
+ final JsonValue value
+ ) {
+ final Class> clazz;
+ try {
+ clazz = Class.forName(confName);
+ } catch (ClassNotFoundException ex) {
+ return Response
+ .status(Response.Status.NOT_FOUND)
+ .entity(
+ String.format("No configuration %s available.", confName))
+ .build();
+ }
+
+ final Object conf;
+ try {
+ conf = confManager.findConfiguration(clazz);
+ } catch (IllegalArgumentException ex) {
+ // We don't expose that we found a class for that name, but that
+ // it is not an Configuration class.
+ return Response
+ .status(Response.Status.NOT_FOUND)
+ .entity(
+ String.format("No configuration %s available.", confName))
+ .build();
+ }
+
+ final Field field;
+ try {
+ field = clazz.getDeclaredField(setting);
+ } catch (NoSuchFieldException ex) {
+ return Response
+ .status(Response.Status.NOT_FOUND)
+ .entity(
+ String.format(
+ "The configuration \"%s\" has not setting \"%s\".",
+ confName,
+ setting
+ )
+ )
+ .build();
+ }
+
+ field.setAccessible(true);
+
+ final ConfigurationInfo confInfo = confManager
+ .getConfigurationInfo(clazz);
+
+ final SettingInfo settingInfo = confInfo.getSettings().get(setting);
+ final String valueType = settingInfo.getValueType();
+ final SettingValueConverter> converter = converters.get(valueType);
+ if (converter == null) {
+ return Response.
+ status(Response.Status.INTERNAL_SERVER_ERROR)
+ .entity(
+ String.format(
+ "No converter available for type \"%s\" of "
+ + "setting \"%s\" of configuration \"%s\".",
+ valueType,
+ setting,
+ confName
+ )
+ )
+ .build();
+ }
+
+ try {
+ field.set(conf, converter.convertSettingValue(value));
+ } catch (IllegalAccessException ex) {
+ LOGGER.error(
+ "Unable to set value of setting \"{}\" of "
+ + "configuration \"{}\".",
+ setting,
+ confName
+ );
+ LOGGER.error(ex);
+ return Response
+ .status(Response.Status.INTERNAL_SERVER_ERROR)
+ .entity(
+ String.format(
+ "Unable to set value of setting \"%s\" of "
+ + "configuration \"%s\".",
+ setting,
+ confName
+ )
+ )
+ .build();
+ } catch (IllegalArgumentException ex) {
+ LOGGER.error(
+ "Provided value of type \"{}\" can't be used for "
+ + "setting of type \"{}\".",
+ Objects.toString(value.getValueType()),
+ valueType
+ );
+ LOGGER.error(ex);
+ return Response
+ .status(Response.Status.INTERNAL_SERVER_ERROR)
+ .entity(
+ String.format(
+ "Provided value of type \"%s\" can't be used for "
+ + "setting of type \"%s\".",
+ Objects.toString(value.getValueType()),
+ valueType
+ )
+ )
+ .build();
+ }
+
+ return Response
+ .ok(
+ String.format(
+ "Setting \"%s\" of configuration \"%s\" successfully "
+ + "updated",
+ setting,
+ confName
+ )
+ )
+ .build();
+ }
+
+}
diff --git a/ccm-core/src/main/java/org/libreccm/api/admin/configuration/DoubleConverter.java b/ccm-core/src/main/java/org/libreccm/api/admin/configuration/DoubleConverter.java
new file mode 100644
index 000000000..c88251188
--- /dev/null
+++ b/ccm-core/src/main/java/org/libreccm/api/admin/configuration/DoubleConverter.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2020 LibreCCM Foundation.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+package org.libreccm.api.admin.configuration;
+
+import javax.json.JsonNumber;
+import javax.json.JsonValue;
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.Response;
+
+/**
+ *
+ * @author Jens Pelzetter
+ */
+class DoubleConverter implements SettingValueConverter {
+
+ @Override
+ public Double convertSettingValue(final JsonValue value) {
+ if (value.getValueType() == JsonValue.ValueType.NUMBER) {
+ return ((JsonNumber) value).doubleValue();
+ } else {
+ throw new WebApplicationException(
+ "The provided value is not a number.",
+ Response.Status.BAD_REQUEST
+ );
+ }
+ }
+
+}
diff --git a/ccm-core/src/main/java/org/libreccm/api/admin/configuration/EnumConverter.java b/ccm-core/src/main/java/org/libreccm/api/admin/configuration/EnumConverter.java
new file mode 100644
index 000000000..3385e36a6
--- /dev/null
+++ b/ccm-core/src/main/java/org/libreccm/api/admin/configuration/EnumConverter.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2020 LibreCCM Foundation.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+package org.libreccm.api.admin.configuration;
+
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import javax.json.JsonArray;
+import javax.json.JsonString;
+import javax.json.JsonValue;
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.Response;
+
+/**
+ *
+ * @author Jens Pelzetter
+ */
+class EnumConverter
+ implements SettingValueConverter> {
+
+ @Override
+ public Set convertSettingValue(final JsonValue value) {
+ if (value.getValueType() == JsonValue.ValueType.ARRAY) {
+ final JsonArray array = value.asJsonArray();
+ return array
+ .stream()
+ .map(this::convertEnumValue)
+ .collect(Collectors.toSet());
+ } else {
+ throw new WebApplicationException(
+ "The provided value is not an array.",
+ Response.Status.BAD_REQUEST
+ );
+ }
+ }
+
+ private String convertEnumValue(final JsonValue value) {
+ if (value.getValueType() == JsonValue.ValueType.STRING) {
+ return ((JsonString) value).getString();
+ } else {
+ throw new WebApplicationException(
+ "One of the provided values is not a string.",
+ Response.Status.BAD_REQUEST
+ );
+ }
+ }
+
+}
diff --git a/ccm-core/src/main/java/org/libreccm/api/admin/configuration/LocalizedStringConverter.java b/ccm-core/src/main/java/org/libreccm/api/admin/configuration/LocalizedStringConverter.java
new file mode 100644
index 000000000..a38dde1de
--- /dev/null
+++ b/ccm-core/src/main/java/org/libreccm/api/admin/configuration/LocalizedStringConverter.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2020 LibreCCM Foundation.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+package org.libreccm.api.admin.configuration;
+
+import org.libreccm.l10n.LocalizedString;
+
+import java.util.IllformedLocaleException;
+import java.util.Locale;
+import java.util.Map;
+
+import javax.json.JsonObject;
+import javax.json.JsonString;
+import javax.json.JsonValue;
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.Response;
+
+/**
+ *
+ * @author Jens Pelzetter
+ */
+public class LocalizedStringConverter
+ implements SettingValueConverter {
+
+ @Override
+ public LocalizedString convertSettingValue(final JsonValue value) {
+ if (value.getValueType() == JsonValue.ValueType.OBJECT) {
+ final JsonObject object = value.asJsonObject();
+ final LocalizedString localizedString = new LocalizedString();
+ object
+ .entrySet()
+ .stream()
+ .map(this::buildLocalizedValue)
+ .forEach(
+ localized -> localizedString.addValue(
+ localized.getLocale(),
+ localized.getValue()
+ )
+ );
+ return localizedString;
+ } else {
+ throw new WebApplicationException(
+ "One of the provided values is not an object.",
+ Response.Status.BAD_REQUEST
+ );
+ }
+ }
+
+ private LocalizedValue buildLocalizedValue(
+ final Map.Entry entry
+ ) {
+ final JsonValue value = entry.getValue();
+ if (value.getValueType() == JsonValue.ValueType.STRING) {
+ final Locale.Builder localeBuilder = new Locale.Builder();
+ final Locale locale;
+ try {
+ locale = new Locale.Builder()
+ .setLanguageTag(entry.getKey())
+ .build();
+ } catch (IllformedLocaleException ex) {
+ throw new WebApplicationException(
+ String.format(
+ "\"%s\" is not a valid locale.", entry.getKey()
+ ),
+ Response.Status.BAD_REQUEST
+ );
+ }
+ return new LocalizedValue(locale, ((JsonString) value).getString());
+ } else {
+ throw new WebApplicationException(
+ String.format(
+ "Value for locale \"%s\" is not a string.",
+ entry.getKey()
+ ),
+ Response.Status.BAD_REQUEST
+ );
+ }
+
+ }
+
+ private class LocalizedValue {
+
+ private final Locale locale;
+
+ private final String value;
+
+ public LocalizedValue(Locale locale, String value) {
+ this.locale = locale;
+ this.value = value;
+ }
+
+ public Locale getLocale() {
+ return locale;
+ }
+
+ public String getValue() {
+ return value;
+ }
+
+ }
+
+}
diff --git a/ccm-core/src/main/java/org/libreccm/api/admin/configuration/LongConverter.java b/ccm-core/src/main/java/org/libreccm/api/admin/configuration/LongConverter.java
new file mode 100644
index 000000000..b72de2e16
--- /dev/null
+++ b/ccm-core/src/main/java/org/libreccm/api/admin/configuration/LongConverter.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2020 LibreCCM Foundation.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+package org.libreccm.api.admin.configuration;
+
+import javax.json.JsonNumber;
+import javax.json.JsonValue;
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.Response;
+
+/**
+ *
+ * @author Jens Pelzetter
+ */
+public class LongConverter implements SettingValueConverter {
+
+ @Override
+ public Long convertSettingValue(final JsonValue value) {
+ if (value.getValueType() == JsonValue.ValueType.NUMBER) {
+ return ((JsonNumber) value).longValue();
+ } else {
+ throw new WebApplicationException(
+ "The provided value is not a number.",
+ Response.Status.BAD_REQUEST
+ );
+ }
+ }
+}
diff --git a/ccm-core/src/main/java/org/libreccm/api/admin/configuration/SettingValueConverter.java b/ccm-core/src/main/java/org/libreccm/api/admin/configuration/SettingValueConverter.java
new file mode 100644
index 000000000..a90d8a3e5
--- /dev/null
+++ b/ccm-core/src/main/java/org/libreccm/api/admin/configuration/SettingValueConverter.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2020 LibreCCM Foundation.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+package org.libreccm.api.admin.configuration;
+
+import javax.json.JsonValue;
+
+/**
+ * Interface for the setting value converters.
+ *
+ * @author Jens Pelzetter
+ * @param Value Type
+ */
+interface SettingValueConverter {
+
+ T convertSettingValue(JsonValue value);
+
+}
diff --git a/ccm-core/src/main/java/org/libreccm/api/admin/configuration/StringConverter.java b/ccm-core/src/main/java/org/libreccm/api/admin/configuration/StringConverter.java
new file mode 100644
index 000000000..cd44800e7
--- /dev/null
+++ b/ccm-core/src/main/java/org/libreccm/api/admin/configuration/StringConverter.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2020 LibreCCM Foundation.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+package org.libreccm.api.admin.configuration;
+
+import javax.json.JsonString;
+import javax.json.JsonValue;
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.Response;
+
+/**
+ *
+ * @author Jens Pelzetter
+ */
+class StringConverter implements SettingValueConverter {
+
+ @Override
+ public String convertSettingValue(final JsonValue value) {
+ if (value.getValueType() == JsonValue.ValueType.STRING) {
+ return ((JsonString) value).getString();
+ } else {
+ throw new WebApplicationException(
+ "The provided value is not a string.",
+ Response.Status.BAD_REQUEST
+ );
+ }
+ }
+
+}
diff --git a/ccm-core/src/main/java/org/libreccm/api/admin/configuration/StringListConverter.java b/ccm-core/src/main/java/org/libreccm/api/admin/configuration/StringListConverter.java
new file mode 100644
index 000000000..703fa1295
--- /dev/null
+++ b/ccm-core/src/main/java/org/libreccm/api/admin/configuration/StringListConverter.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2020 LibreCCM Foundation.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+package org.libreccm.api.admin.configuration;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+import javax.json.JsonString;
+import javax.json.JsonValue;
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.Response;
+
+/**
+ *
+ * @author Jens Pelzetter
+ */
+public class StringListConverter implements SettingValueConverter>{
+
+ @Override
+ public List convertSettingValue(final JsonValue value) {
+ if (value.getValueType() == JsonValue.ValueType.STRING) {
+ return value
+ .asJsonArray()
+ .stream()
+ .map(this::convertValue)
+ .collect(Collectors.toList());
+ } else {
+ throw new WebApplicationException(
+ "The provided value is not an array.",
+ Response.Status.BAD_REQUEST
+ );
+ }
+ }
+
+ private String convertValue(final JsonValue value) {
+ if (value.getValueType() == JsonValue.ValueType.STRING) {
+ return ((JsonString) value).getString();
+ } else {
+ throw new WebApplicationException(
+ "One of the values in the array is not a string.",
+ Response.Status.BAD_REQUEST
+ );
+ }
+ }
+}
diff --git a/ccm-core/src/main/java/org/libreccm/configuration/ConfigurationManager.java b/ccm-core/src/main/java/org/libreccm/configuration/ConfigurationManager.java
index f33c551f5..f4ffcdef3 100644
--- a/ccm-core/src/main/java/org/libreccm/configuration/ConfigurationManager.java
+++ b/ccm-core/src/main/java/org/libreccm/configuration/ConfigurationManager.java
@@ -81,18 +81,23 @@ public class ConfigurationManager implements Serializable {
CcmModule.class);
final SortedSet> configurations = new TreeSet<>(
- (conf1, conf2) -> conf1.getName().compareTo(conf2.getName()));
+ (conf1, conf2) -> conf1.getName().compareTo(conf2.getName())
+ );
for (CcmModule module : modules) {
final Module annotation = module.getClass().getAnnotation(
- Module.class);
+ Module.class
+ );
if (annotation == null) {
continue;
}
final List> moduleConfs = Arrays.stream(
- annotation.configurations()).collect(Collectors.toList());
+ annotation.configurations()
+ ).collect(
+ Collectors.toList()
+ );
configurations.addAll(moduleConfs);
}
@@ -367,7 +372,7 @@ public class ConfigurationManager implements Serializable {
return null;
} catch (InvocationTargetException | NoSuchMethodException e) {
LOGGER.error(e);
- return null;
+ return null;
}
final List settingList = settingManager
diff --git a/ccm-core/src/main/java/org/libreccm/configuration/EnumSetting.java b/ccm-core/src/main/java/org/libreccm/configuration/EnumSetting.java
index 1f4bacd7f..3380d43ae 100644
--- a/ccm-core/src/main/java/org/libreccm/configuration/EnumSetting.java
+++ b/ccm-core/src/main/java/org/libreccm/configuration/EnumSetting.java
@@ -18,12 +18,22 @@
*/
package org.libreccm.configuration;
-import javax.persistence.*;
import java.io.Serializable;
-import java.util.*;
import static org.libreccm.core.CoreConstants.DB_SCHEMA;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Objects;
+import java.util.Set;
+
+import javax.persistence.ElementCollection;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.JoinColumn;
+import javax.persistence.JoinTable;
+
/**
* A setting class for storing a set of strings. This can be used to generate
* enums which can be configured by the administrator.