RESTful API for configuration
parent
0b9c2e9b27
commit
98f5d3201b
|
|
@ -20,6 +20,7 @@ import org.libreccm.api.DefaultResponseHeaders;
|
||||||
import org.libreccm.api.PreflightRequestFilter;
|
import org.libreccm.api.PreflightRequestFilter;
|
||||||
import org.libreccm.api.admin.categorization.CategoriesApi;
|
import org.libreccm.api.admin.categorization.CategoriesApi;
|
||||||
import org.libreccm.api.admin.categorization.DomainsApi;
|
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(DomainsApi.class);
|
||||||
classes.add(CategoriesApi.class);
|
classes.add(CategoriesApi.class);
|
||||||
|
|
||||||
|
// Configuration API
|
||||||
|
classes.add(Configuration.class);
|
||||||
|
|
||||||
// Security API
|
// Security API
|
||||||
classes.add(GroupsApi.class);
|
classes.add(GroupsApi.class);
|
||||||
classes.add(RolesApi.class);
|
classes.add(RolesApi.class);
|
||||||
|
|
|
||||||
|
|
@ -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 <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
|
*/
|
||||||
|
class BigDecimalConverter implements SettingValueConverter<BigDecimal> {
|
||||||
|
|
||||||
|
@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
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -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 <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
|
*/
|
||||||
|
class BooleanConverter implements SettingValueConverter<Boolean> {
|
||||||
|
|
||||||
|
@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
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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 <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
|
*/
|
||||||
|
@RequestScoped
|
||||||
|
@Path("/configuration")
|
||||||
|
public class ConfigurationApi {
|
||||||
|
|
||||||
|
private static final Logger LOGGER = LogManager.getLogger(
|
||||||
|
ConfigurationApi.class
|
||||||
|
);
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private ConfigurationManager confManager;
|
||||||
|
|
||||||
|
private final Map<String, SettingValueConverter<?>> 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<ConfigurationInfo> 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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -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 <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
|
*/
|
||||||
|
class DoubleConverter implements SettingValueConverter<Double> {
|
||||||
|
|
||||||
|
@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
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -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 <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
|
*/
|
||||||
|
class EnumConverter
|
||||||
|
implements SettingValueConverter<Set<String>> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<String> 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
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -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 <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
|
*/
|
||||||
|
public class LocalizedStringConverter
|
||||||
|
implements SettingValueConverter<LocalizedString> {
|
||||||
|
|
||||||
|
@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<String, JsonValue> 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -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 <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
|
*/
|
||||||
|
public class LongConverter implements SettingValueConverter<Long> {
|
||||||
|
|
||||||
|
@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
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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 <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
|
* @param <T> Value Type
|
||||||
|
*/
|
||||||
|
interface SettingValueConverter<T> {
|
||||||
|
|
||||||
|
T convertSettingValue(JsonValue value);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -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 <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
|
*/
|
||||||
|
class StringConverter implements SettingValueConverter<String> {
|
||||||
|
|
||||||
|
@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
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -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 <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
|
*/
|
||||||
|
public class StringListConverter implements SettingValueConverter<List<String>>{
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> 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
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -81,18 +81,23 @@ public class ConfigurationManager implements Serializable {
|
||||||
CcmModule.class);
|
CcmModule.class);
|
||||||
|
|
||||||
final SortedSet<Class<?>> configurations = new TreeSet<>(
|
final SortedSet<Class<?>> configurations = new TreeSet<>(
|
||||||
(conf1, conf2) -> conf1.getName().compareTo(conf2.getName()));
|
(conf1, conf2) -> conf1.getName().compareTo(conf2.getName())
|
||||||
|
);
|
||||||
|
|
||||||
for (CcmModule module : modules) {
|
for (CcmModule module : modules) {
|
||||||
final Module annotation = module.getClass().getAnnotation(
|
final Module annotation = module.getClass().getAnnotation(
|
||||||
Module.class);
|
Module.class
|
||||||
|
);
|
||||||
|
|
||||||
if (annotation == null) {
|
if (annotation == null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
final List<Class<?>> moduleConfs = Arrays.stream(
|
final List<Class<?>> moduleConfs = Arrays.stream(
|
||||||
annotation.configurations()).collect(Collectors.toList());
|
annotation.configurations()
|
||||||
|
).collect(
|
||||||
|
Collectors.toList()
|
||||||
|
);
|
||||||
|
|
||||||
configurations.addAll(moduleConfs);
|
configurations.addAll(moduleConfs);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,12 +18,22 @@
|
||||||
*/
|
*/
|
||||||
package org.libreccm.configuration;
|
package org.libreccm.configuration;
|
||||||
|
|
||||||
import javax.persistence.*;
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
import static org.libreccm.core.CoreConstants.DB_SCHEMA;
|
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
|
* A setting class for storing a set of strings. This can be used to generate
|
||||||
* enums which can be configured by the administrator.
|
* enums which can be configured by the administrator.
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue