CCM NG: Split class ConfigurationManager into smaller classes to reduce complexity.
git-svn-id: https://svn.libreccm.org/ccm/ccm_ng@3825 8810af33-2d31-482b-a856-94f89814c4dfpull/2/head
parent
cc7889143c
commit
73eef4aeb0
|
|
@ -20,7 +20,6 @@ package org.libreccm.categorization;
|
||||||
|
|
||||||
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.apache.logging.log4j.message.FormattedMessage;
|
|
||||||
import org.libreccm.core.AbstractEntityRepository;
|
import org.libreccm.core.AbstractEntityRepository;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,194 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2016 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.configuration;
|
||||||
|
|
||||||
|
import static org.libreccm.configuration.ConfigurationConstants.*;
|
||||||
|
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.libreccm.categorization.Category;
|
||||||
|
import org.libreccm.categorization.CategoryManager;
|
||||||
|
import org.libreccm.categorization.CategoryRepository;
|
||||||
|
import org.libreccm.categorization.Domain;
|
||||||
|
import org.libreccm.categorization.DomainRepository;
|
||||||
|
import org.libreccm.web.CcmApplication;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
|
||||||
|
import javax.enterprise.context.RequestScoped;
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.persistence.EntityManager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
|
*/
|
||||||
|
@RequestScoped
|
||||||
|
public class ApplicationConfigurationManager {
|
||||||
|
|
||||||
|
private static final Logger LOGGER = LogManager.getLogger(
|
||||||
|
ApplicationConfigurationManager.class
|
||||||
|
);
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private ConfigurationManager confManager;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private SettingManager settingManager;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private SettingConverter settingConverter;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private DomainRepository domainRepo;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private CategoryRepository categoryRepo;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private CategoryManager categoryManager;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private EntityManager entityManager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds an application instance specific configuration and loads it values
|
||||||
|
* from the registry.
|
||||||
|
*
|
||||||
|
* @param <T> The type of the configuration.
|
||||||
|
* @param confClass The configuration class.
|
||||||
|
* @param instance The application instance for which the settings are
|
||||||
|
* loaded.
|
||||||
|
*
|
||||||
|
* @return The configuration for the provided application instance.
|
||||||
|
*/
|
||||||
|
public <T extends ApplicationConfiguration> T findConfiguration(
|
||||||
|
final Class<T> confClass, final CcmApplication instance) {
|
||||||
|
if (confClass == null) {
|
||||||
|
throw new IllegalArgumentException("confClass can't be null");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (instance == null) {
|
||||||
|
throw new IllegalArgumentException("instance can't be null");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (confClass.getAnnotation(Configuration.class) == null) {
|
||||||
|
throw new IllegalArgumentException(String.format(
|
||||||
|
"Provided class \"%s\" is not annotated with \"%s\".",
|
||||||
|
confClass.getName(),
|
||||||
|
Configuration.class.getName()));
|
||||||
|
}
|
||||||
|
|
||||||
|
final String confName = String.format("%s.%s",
|
||||||
|
confClass.getName(),
|
||||||
|
instance.getPrimaryUrl());
|
||||||
|
|
||||||
|
return confManager.findConfiguration(confName, confClass);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Saves a application instance configuration.
|
||||||
|
*
|
||||||
|
* @param configuration The configuration to save.
|
||||||
|
* @param instance The application instance of which the configuration
|
||||||
|
* stores the settings.
|
||||||
|
*/
|
||||||
|
public void saveConfiguration(final ApplicationConfiguration configuration,
|
||||||
|
final CcmApplication instance) {
|
||||||
|
if (configuration == null) {
|
||||||
|
throw new IllegalArgumentException("Configuration can't be null");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (configuration.getClass().getAnnotation(Configuration.class) == null) {
|
||||||
|
throw new IllegalArgumentException(String.format(
|
||||||
|
"The class \"%s\" of the provided object is not annotated "
|
||||||
|
+ "with \"%s\".",
|
||||||
|
configuration.getClass().getName(),
|
||||||
|
Configuration.class.getName()));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (instance == null) {
|
||||||
|
throw new IllegalArgumentException("Instance can't be null");
|
||||||
|
}
|
||||||
|
|
||||||
|
final Field[] fields = configuration.getClass().getDeclaredFields();
|
||||||
|
for (final Field field : fields) {
|
||||||
|
field.setAccessible(true);
|
||||||
|
try {
|
||||||
|
setSettingValue(configuration,
|
||||||
|
instance,
|
||||||
|
confManager.getSettingName(field),
|
||||||
|
field.getType(),
|
||||||
|
field.get(configuration));
|
||||||
|
} catch (IllegalAccessException ex) {
|
||||||
|
LOGGER.error(String.format(
|
||||||
|
"Failed to write setting value for setting \"%s\" "
|
||||||
|
+ "of configuration \"%s\"",
|
||||||
|
confManager.getSettingName(field),
|
||||||
|
configuration.getClass().getName()),
|
||||||
|
ex);
|
||||||
|
throw new IllegalStateException(String.format(
|
||||||
|
"Failed to write setting value for setting \"%s\" "
|
||||||
|
+ "of configuration \"%s\"",
|
||||||
|
confManager.getSettingName(field),
|
||||||
|
configuration.getClass().getName()),
|
||||||
|
ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the value of a setting of application instance configuration.
|
||||||
|
*
|
||||||
|
* @param <T> The value type of the setting.
|
||||||
|
* @param configuration The configuration to which the settings belongs.
|
||||||
|
* @param instance The application instance to which
|
||||||
|
* @param settingName The name of the setting.
|
||||||
|
* @param valueType The type of the value of the setting.
|
||||||
|
* @param value The value to set.
|
||||||
|
*/
|
||||||
|
private <T> void setSettingValue(final Object configuration,
|
||||||
|
final CcmApplication instance,
|
||||||
|
final String settingName,
|
||||||
|
final Class<T> valueType,
|
||||||
|
final Object value) {
|
||||||
|
final String settingPath = String.format(
|
||||||
|
"%s.%s.%s",
|
||||||
|
configuration.getClass().getName(),
|
||||||
|
instance.getPrimaryUrl(),
|
||||||
|
settingName);
|
||||||
|
AbstractSetting<T> setting = settingManager.findSetting(settingPath, valueType);
|
||||||
|
if (setting == null) {
|
||||||
|
setting = settingConverter.createSettingForValueType(valueType);
|
||||||
|
setting.setName(settingName);
|
||||||
|
final Domain registry = domainRepo
|
||||||
|
.findByDomainKey(REGISTRY_DOMAIN);
|
||||||
|
final Category category = categoryRepo
|
||||||
|
.findByPath(registry, configuration.getClass().getName());
|
||||||
|
categoryManager.addObjectToCategory(setting, category);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
final T settingValue = (T) value;
|
||||||
|
setting.setValue(settingValue);
|
||||||
|
|
||||||
|
entityManager.merge(setting);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -23,22 +23,13 @@ import static org.libreccm.configuration.ConfigurationConstants.*;
|
||||||
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.apache.logging.log4j.message.FormattedMessage;
|
import org.apache.logging.log4j.message.FormattedMessage;
|
||||||
import org.libreccm.categorization.Categorization;
|
|
||||||
import org.libreccm.categorization.Category;
|
import org.libreccm.categorization.Category;
|
||||||
import org.libreccm.categorization.CategoryManager;
|
import org.libreccm.categorization.CategoryManager;
|
||||||
import org.libreccm.categorization.CategoryRepository;
|
import org.libreccm.categorization.CategoryRepository;
|
||||||
import org.libreccm.categorization.Domain;
|
import org.libreccm.categorization.Domain;
|
||||||
import org.libreccm.categorization.DomainRepository;
|
import org.libreccm.categorization.DomainRepository;
|
||||||
import org.libreccm.core.CcmObject;
|
|
||||||
import org.libreccm.l10n.LocalizedString;
|
|
||||||
import org.libreccm.web.CcmApplication;
|
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.math.BigDecimal;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.StringJoiner;
|
import java.util.StringJoiner;
|
||||||
|
|
||||||
import javax.enterprise.context.RequestScoped;
|
import javax.enterprise.context.RequestScoped;
|
||||||
|
|
@ -51,24 +42,25 @@ import javax.persistence.EntityManager;
|
||||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
*/
|
*/
|
||||||
@RequestScoped
|
@RequestScoped
|
||||||
@SuppressWarnings({"PMD.GodClass",
|
|
||||||
"PMD.TooManyMethods",
|
|
||||||
"PMD.LongVariable",
|
|
||||||
"PMD.ModifiedCyclomaticComplexity",
|
|
||||||
"PMD.StandardCyclomaticComplexity",})
|
|
||||||
public class ConfigurationManager {
|
public class ConfigurationManager {
|
||||||
|
|
||||||
private static final Logger LOGGER = LogManager.getLogger(
|
private static final Logger LOGGER = LogManager.getLogger(
|
||||||
ConfigurationManager.class);
|
ConfigurationManager.class);
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private SettingManager settingManager;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private SettingConverter settingConverter;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private CategoryManager categoryManager;
|
private CategoryManager categoryManager;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private CategoryRepository categoryRepository;
|
private CategoryRepository categoryRepo;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private DomainRepository domainRepository;
|
private DomainRepository domainRepo;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private EntityManager entityManager;
|
private EntityManager entityManager;
|
||||||
|
|
@ -162,92 +154,6 @@ public class ConfigurationManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Finds an application instance specific configuration and loads it values
|
|
||||||
* from the registry.
|
|
||||||
*
|
|
||||||
* @param <T> The type of the configuration.
|
|
||||||
* @param confClass The configuration class.
|
|
||||||
* @param instance The application instance for which the settings are
|
|
||||||
* loaded.
|
|
||||||
*
|
|
||||||
* @return The configuration for the provided application instance.
|
|
||||||
*/
|
|
||||||
public <T extends ApplicationConfiguration> T findConfiguration(
|
|
||||||
final Class<T> confClass, final CcmApplication instance) {
|
|
||||||
if (confClass == null) {
|
|
||||||
throw new IllegalArgumentException("confClass can't be null");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (instance == null) {
|
|
||||||
throw new IllegalArgumentException("instance can't be null");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (confClass.getAnnotation(Configuration.class) == null) {
|
|
||||||
throw new IllegalArgumentException(String.format(
|
|
||||||
"Provided class \"%s\" is not annotated with \"%s\".",
|
|
||||||
confClass.getName(),
|
|
||||||
Configuration.class.getName()));
|
|
||||||
}
|
|
||||||
|
|
||||||
final String confName = String.format("%s.%s",
|
|
||||||
confClass.getName(),
|
|
||||||
instance.getPrimaryUrl());
|
|
||||||
|
|
||||||
return findConfiguration(confName, confClass);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Saves a application instance configuration.
|
|
||||||
*
|
|
||||||
* @param configuration The configuration to save.
|
|
||||||
* @param instance The application instance of which the configuration
|
|
||||||
* stores the settings.
|
|
||||||
*/
|
|
||||||
public void saveConfiguration(final ApplicationConfiguration configuration,
|
|
||||||
final CcmApplication instance) {
|
|
||||||
if (configuration == null) {
|
|
||||||
throw new IllegalArgumentException("Configuration can't be null");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (configuration.getClass().getAnnotation(Configuration.class) == null) {
|
|
||||||
throw new IllegalArgumentException(String.format(
|
|
||||||
"The class \"%s\" of the provided object is not annotated "
|
|
||||||
+ "with \"%s\".",
|
|
||||||
configuration.getClass().getName(),
|
|
||||||
Configuration.class.getName()));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (instance == null) {
|
|
||||||
throw new IllegalArgumentException("Instance can't be null");
|
|
||||||
}
|
|
||||||
|
|
||||||
final Field[] fields = configuration.getClass().getDeclaredFields();
|
|
||||||
for (final Field field : fields) {
|
|
||||||
field.setAccessible(true);
|
|
||||||
try {
|
|
||||||
setSettingValue(configuration,
|
|
||||||
instance,
|
|
||||||
getSettingName(field),
|
|
||||||
field.getType(),
|
|
||||||
field.get(configuration));
|
|
||||||
} catch (IllegalAccessException ex) {
|
|
||||||
LOGGER.error(String.format(
|
|
||||||
"Failed to write setting value for setting \"%s\" "
|
|
||||||
+ "of configuration \"%s\"",
|
|
||||||
getSettingName(field),
|
|
||||||
configuration.getClass().getName()),
|
|
||||||
ex);
|
|
||||||
throw new IllegalStateException(String.format(
|
|
||||||
"Failed to write setting value for setting \"%s\" "
|
|
||||||
+ "of configuration \"%s\"",
|
|
||||||
getSettingName(field),
|
|
||||||
configuration.getClass().getName()),
|
|
||||||
ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the {@link ConfigurationInfo} for a configuration.
|
* Get the {@link ConfigurationInfo} for a configuration.
|
||||||
*
|
*
|
||||||
|
|
@ -294,205 +200,14 @@ public class ConfigurationManager {
|
||||||
for (final Field field : fields) {
|
for (final Field field : fields) {
|
||||||
field.setAccessible(true);
|
field.setAccessible(true);
|
||||||
if (field.getAnnotation(Setting.class) != null) {
|
if (field.getAnnotation(Setting.class) != null) {
|
||||||
confInfo.addSetting(getSettingInfo(configuration,
|
confInfo.addSetting(settingManager.getSettingInfo(
|
||||||
field.getName()));
|
configuration, field.getName()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return confInfo;
|
return confInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a {@link SettingInfo} instance for a setting.
|
|
||||||
*
|
|
||||||
* @param configuration The configuration class to which the settings
|
|
||||||
* belongs.
|
|
||||||
* @param name The name of the setting for which the
|
|
||||||
* {@link SettingInfo} is generated.
|
|
||||||
*
|
|
||||||
* @return The {@link SettingInfo} for the provided configuration class.
|
|
||||||
*/
|
|
||||||
@SuppressWarnings({"PMD.NPathComplexity",
|
|
||||||
"PMD.CyclomaticComplexity",
|
|
||||||
"PMD.StandardCyclomaticComplexity"})
|
|
||||||
public SettingInfo getSettingInfo(final Class<?> configuration,
|
|
||||||
final String name) {
|
|
||||||
if (configuration == null) {
|
|
||||||
throw new IllegalArgumentException("Configuration can't be null");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (configuration.getAnnotation(Configuration.class) == null) {
|
|
||||||
throw new IllegalArgumentException(String.format(
|
|
||||||
"The class \"%s\" of the provided object is not annotated "
|
|
||||||
+ "with \"%s\".",
|
|
||||||
configuration.getClass().getName(),
|
|
||||||
Configuration.class.getName()));
|
|
||||||
}
|
|
||||||
|
|
||||||
final Configuration confAnnotation = configuration.getAnnotation(
|
|
||||||
Configuration.class);
|
|
||||||
final String descBundle;
|
|
||||||
if (confAnnotation.descBundle() == null
|
|
||||||
|| confAnnotation.descBundle().isEmpty()) {
|
|
||||||
descBundle = String.join("",
|
|
||||||
configuration.getClass().getName(),
|
|
||||||
"Description");
|
|
||||||
} else {
|
|
||||||
descBundle = confAnnotation.descBundle();
|
|
||||||
}
|
|
||||||
|
|
||||||
final Field field;
|
|
||||||
try {
|
|
||||||
field = configuration.getDeclaredField(name);
|
|
||||||
} catch (SecurityException | NoSuchFieldException ex) {
|
|
||||||
LOGGER.warn(String.format(
|
|
||||||
"Failed to generate SettingInfo for field \"%s\" of "
|
|
||||||
+ "configuration \"%s\". Ignoring field.",
|
|
||||||
configuration.getClass().getName(),
|
|
||||||
name),
|
|
||||||
ex);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (field.getAnnotation(Setting.class) == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
final Setting settingAnnotation = field.getAnnotation(Setting.class);
|
|
||||||
final SettingInfo settingInfo = new SettingInfo();
|
|
||||||
if (settingAnnotation.name() == null
|
|
||||||
|| settingAnnotation.name().isEmpty()) {
|
|
||||||
settingInfo.setName(field.getName());
|
|
||||||
} else {
|
|
||||||
settingInfo.setName(settingAnnotation.name());
|
|
||||||
}
|
|
||||||
|
|
||||||
settingInfo.setValueType(field.getType().getName());
|
|
||||||
|
|
||||||
try {
|
|
||||||
final Object conf = configuration.newInstance();
|
|
||||||
settingInfo.setDefaultValue(field.get(conf).toString());
|
|
||||||
} catch (InstantiationException | IllegalAccessException ex) {
|
|
||||||
LOGGER.warn(String.format("Failed to create instance of \"%s\" to "
|
|
||||||
+ "get default values.",
|
|
||||||
configuration.getName()),
|
|
||||||
ex);
|
|
||||||
}
|
|
||||||
|
|
||||||
settingInfo.setConfClass(configuration.getName());
|
|
||||||
|
|
||||||
settingInfo.setDescBundle(descBundle);
|
|
||||||
|
|
||||||
if (settingAnnotation.labelKey() == null
|
|
||||||
|| settingAnnotation.labelKey().isEmpty()) {
|
|
||||||
settingInfo.setLabelKey(String.join(".", field.getName(),
|
|
||||||
"label"));
|
|
||||||
} else {
|
|
||||||
settingInfo.setLabelKey(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (settingAnnotation.descKey() == null
|
|
||||||
|| settingAnnotation.descKey().isEmpty()) {
|
|
||||||
settingInfo.setDescKey(String.join(".",
|
|
||||||
field.getName(),
|
|
||||||
"descripotion"));
|
|
||||||
} else {
|
|
||||||
settingInfo.setDescKey(settingAnnotation.descKey());
|
|
||||||
}
|
|
||||||
|
|
||||||
return settingInfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A low level method for finding a setting in the registry.
|
|
||||||
*
|
|
||||||
* @param <T> Type of the value of the setting
|
|
||||||
* @param name The fully qualified name of the setting.
|
|
||||||
* @param clazz The class of the setting.
|
|
||||||
*
|
|
||||||
* @return The requested setting if it exists in the registry, {@code null}
|
|
||||||
* otherwise.
|
|
||||||
*/
|
|
||||||
public <T> AbstractSetting<T> findSetting(final String name,
|
|
||||||
final Class<T> clazz) {
|
|
||||||
LOGGER.debug(String.format(
|
|
||||||
"Trying to find setting \"%s\" of type \"%s\"",
|
|
||||||
name,
|
|
||||||
clazz.getName()));
|
|
||||||
final String[] tokens = name.split("\\.");
|
|
||||||
LOGGER.debug(String.format("Setting name \"%s\" has %d tokens.",
|
|
||||||
name,
|
|
||||||
tokens.length));
|
|
||||||
final String[] categoryTokens = Arrays.copyOfRange(tokens,
|
|
||||||
0,
|
|
||||||
tokens.length - 1);
|
|
||||||
final String categoryPath = String.join(".", categoryTokens);
|
|
||||||
LOGGER.debug(String.format("categoryPath for setting is \"%s\".",
|
|
||||||
categoryPath));
|
|
||||||
|
|
||||||
final Domain registry = domainRepository
|
|
||||||
.findByDomainKey(REGISTRY_DOMAIN);
|
|
||||||
final Category category = categoryRepository.findByPath(registry,
|
|
||||||
categoryPath);
|
|
||||||
if (category == null) {
|
|
||||||
LOGGER.warn(String.format(String.format(
|
|
||||||
"Category \"%s\" for setting \"%s\" not found.",
|
|
||||||
categoryPath,
|
|
||||||
name)));
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
LOGGER.debug(String.format("Category has %d objects. Filtering.",
|
|
||||||
category.getObjects().size()));
|
|
||||||
final Optional<Categorization> result = category
|
|
||||||
.getObjects()
|
|
||||||
.stream()
|
|
||||||
.filter((Categorization c)
|
|
||||||
-> c.getCategorizedObject() instanceof AbstractSetting)
|
|
||||||
.filter((Categorization c)
|
|
||||||
-> ((AbstractSetting<?>) c.getCategorizedObject())
|
|
||||||
.getName()
|
|
||||||
.equals(tokens[tokens.length - 1]))
|
|
||||||
.findFirst();
|
|
||||||
|
|
||||||
if (result.isPresent()) {
|
|
||||||
final CcmObject object = result.get().getCategorizedObject();
|
|
||||||
final AbstractSetting<?> entry = (AbstractSetting<?>) object;
|
|
||||||
|
|
||||||
if (clazz.isInstance(entry.getValue())) {
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
final AbstractSetting<T> resultEntry
|
|
||||||
= (AbstractSetting<T>) entry;
|
|
||||||
return resultEntry;
|
|
||||||
} else {
|
|
||||||
LOGGER.warn(String.format("Setting \"%s\" found but is not of "
|
|
||||||
+ "the requested type \"%s\".",
|
|
||||||
name,
|
|
||||||
clazz.getName()));
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
LOGGER.warn(String.format(
|
|
||||||
"Setting \"%s\" was not found in category \"%s\".",
|
|
||||||
name,
|
|
||||||
categoryPath));
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Low level method of saving a setting.
|
|
||||||
*
|
|
||||||
* @param setting The setting to save.
|
|
||||||
*/
|
|
||||||
public void saveSetting(final AbstractSetting<?> setting) {
|
|
||||||
if (setting.getObjectId() == 0) {
|
|
||||||
entityManager.persist(setting);
|
|
||||||
} else {
|
|
||||||
entityManager.merge(setting);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper method for generating the name of a setting. This method does not
|
* Helper method for generating the name of a setting. This method does not
|
||||||
* check if the provided field is annotated with {@link Setting}. The caller
|
* check if the provided field is annotated with {@link Setting}. The caller
|
||||||
|
|
@ -504,7 +219,7 @@ public class ConfigurationManager {
|
||||||
* @return The name of the field or if the {@link Setting} annotation of the
|
* @return The name of the field or if the {@link Setting} annotation of the
|
||||||
* field has a name value, the value of that field.
|
* field has a name value, the value of that field.
|
||||||
*/
|
*/
|
||||||
private String getSettingName(final Field field) {
|
String getSettingName(final Field field) {
|
||||||
LOGGER.debug(String.format("Trying to get setting name from field: "
|
LOGGER.debug(String.format("Trying to get setting name from field: "
|
||||||
+ "\"%s\"",
|
+ "\"%s\"",
|
||||||
field.getName()));
|
field.getName()));
|
||||||
|
|
@ -528,32 +243,32 @@ public class ConfigurationManager {
|
||||||
* @throws IllegalArgumentException If there is not setting type for the
|
* @throws IllegalArgumentException If there is not setting type for the
|
||||||
* provided value type.
|
* provided value type.
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
// @SuppressWarnings("unchecked")
|
||||||
private <T> AbstractSetting<T> createSettingForValueType(
|
// <T> AbstractSetting<T> createSettingForValueType(
|
||||||
final Class<T> valueType) {
|
// final Class<T> valueType) {
|
||||||
|
//
|
||||||
final String valueTypeName = valueType.getName();
|
// final String valueTypeName = valueType.getName();
|
||||||
if (BigDecimal.class.getName().equals(valueTypeName)) {
|
// if (BigDecimal.class.getName().equals(valueTypeName)) {
|
||||||
return (AbstractSetting<T>) new BigDecimalSetting();
|
// return (AbstractSetting<T>) new BigDecimalSetting();
|
||||||
} else if (Boolean.class.getName().equals(valueTypeName)) {
|
// } else if (Boolean.class.getName().equals(valueTypeName)) {
|
||||||
return (AbstractSetting<T>) new BooleanSetting();
|
// return (AbstractSetting<T>) new BooleanSetting();
|
||||||
} else if (Double.class.getName().equals(valueTypeName)) {
|
// } else if (Double.class.getName().equals(valueTypeName)) {
|
||||||
return (AbstractSetting<T>) new DoubleSetting();
|
// return (AbstractSetting<T>) new DoubleSetting();
|
||||||
} else if (List.class.getName().equals(valueTypeName)) {
|
// } else if (List.class.getName().equals(valueTypeName)) {
|
||||||
return (AbstractSetting<T>) new StringListSetting();
|
// return (AbstractSetting<T>) new StringListSetting();
|
||||||
} else if (LocalizedString.class.getName().equals(valueTypeName)) {
|
// } else if (LocalizedString.class.getName().equals(valueTypeName)) {
|
||||||
return (AbstractSetting<T>) new LocalizedStringSetting();
|
// return (AbstractSetting<T>) new LocalizedStringSetting();
|
||||||
} else if (Long.class.getName().equals(valueTypeName)) {
|
// } else if (Long.class.getName().equals(valueTypeName)) {
|
||||||
return (AbstractSetting<T>) new LongSetting();
|
// return (AbstractSetting<T>) new LongSetting();
|
||||||
} else if (Set.class.getName().equals(valueTypeName)) {
|
// } else if (Set.class.getName().equals(valueTypeName)) {
|
||||||
return (AbstractSetting<T>) new EnumSetting();
|
// return (AbstractSetting<T>) new EnumSetting();
|
||||||
} else if (String.class.getName().equals(valueTypeName)) {
|
// } else if (String.class.getName().equals(valueTypeName)) {
|
||||||
return (AbstractSetting<T>) new StringSetting();
|
// return (AbstractSetting<T>) new StringSetting();
|
||||||
} else {
|
// } else {
|
||||||
throw new IllegalArgumentException(String.format(
|
// throw new IllegalArgumentException(String.format(
|
||||||
"No setting type for value type \"%s\".", valueTypeName));
|
// "No setting type for value type \"%s\".", valueTypeName));
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets a value on a setting in the registry.
|
* Sets a value on a setting in the registry.
|
||||||
|
|
@ -576,12 +291,13 @@ public class ConfigurationManager {
|
||||||
"Saving setting \"%s\" of type \"%s\"...",
|
"Saving setting \"%s\" of type \"%s\"...",
|
||||||
settingPath,
|
settingPath,
|
||||||
valueType.getName()));
|
valueType.getName()));
|
||||||
AbstractSetting<T> setting = findSetting(settingPath, valueType);
|
AbstractSetting<T> setting = settingManager.findSetting(settingPath,
|
||||||
|
valueType);
|
||||||
if (setting == null) {
|
if (setting == null) {
|
||||||
LOGGER.debug(String.format("Setting \"%s\" does not yet exist in "
|
LOGGER.debug(String.format("Setting \"%s\" does not yet exist in "
|
||||||
+ "database. Creating new setting.",
|
+ "database. Creating new setting.",
|
||||||
settingPath));
|
settingPath));
|
||||||
setting = createSettingForValueType(valueType);
|
setting = settingConverter.createSettingForValueType(valueType);
|
||||||
setting.setName(settingName);
|
setting.setName(settingName);
|
||||||
setting.setDisplayName(settingName);
|
setting.setDisplayName(settingName);
|
||||||
final Category category = findCategoryForNewSetting(configuration);
|
final Category category = findCategoryForNewSetting(configuration);
|
||||||
|
|
@ -603,44 +319,6 @@ public class ConfigurationManager {
|
||||||
entityManager.flush();
|
entityManager.flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the value of a setting of application instance configuration.
|
|
||||||
*
|
|
||||||
* @param <T> The value type of the setting.
|
|
||||||
* @param configuration The configuration to which the settings belongs.
|
|
||||||
* @param instance The application instance to which
|
|
||||||
* @param settingName The name of the setting.
|
|
||||||
* @param valueType The type of the value of the setting.
|
|
||||||
* @param value The value to set.
|
|
||||||
*/
|
|
||||||
private <T> void setSettingValue(final Object configuration,
|
|
||||||
final CcmApplication instance,
|
|
||||||
final String settingName,
|
|
||||||
final Class<T> valueType,
|
|
||||||
final Object value) {
|
|
||||||
final String settingPath = String.format(
|
|
||||||
"%s.%s.%s",
|
|
||||||
configuration.getClass().getName(),
|
|
||||||
instance.getPrimaryUrl(),
|
|
||||||
settingName);
|
|
||||||
AbstractSetting<T> setting = findSetting(settingPath, valueType);
|
|
||||||
if (setting == null) {
|
|
||||||
setting = createSettingForValueType(valueType);
|
|
||||||
setting.setName(settingName);
|
|
||||||
final Domain registry = domainRepository
|
|
||||||
.findByDomainKey(REGISTRY_DOMAIN);
|
|
||||||
final Category category = categoryRepository
|
|
||||||
.findByPath(registry, configuration.getClass().getName());
|
|
||||||
categoryManager.addObjectToCategory(setting, category);
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
final T settingValue = (T) value;
|
|
||||||
setting.setValue(settingValue);
|
|
||||||
|
|
||||||
entityManager.merge(setting);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper method for loading a configuration from the registry.
|
* Helper method for loading a configuration from the registry.
|
||||||
*
|
*
|
||||||
|
|
@ -657,13 +335,8 @@ public class ConfigurationManager {
|
||||||
* @return An instance of the configuration class with all setting fields
|
* @return An instance of the configuration class with all setting fields
|
||||||
* set to the values stored in the registry.
|
* set to the values stored in the registry.
|
||||||
*/
|
*/
|
||||||
private <T> T findConfiguration(final String confName,
|
<T> T findConfiguration(final String confName,
|
||||||
final Class<T> confClass) {
|
final Class<T> confClass) {
|
||||||
final Domain registry = domainRepository
|
|
||||||
.findByDomainKey(REGISTRY_DOMAIN);
|
|
||||||
final Category category = categoryRepository.findByPath(registry,
|
|
||||||
confName);
|
|
||||||
|
|
||||||
final T conf;
|
final T conf;
|
||||||
try {
|
try {
|
||||||
conf = confClass.newInstance();
|
conf = confClass.newInstance();
|
||||||
|
|
@ -675,7 +348,9 @@ public class ConfigurationManager {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (category == null) {
|
final Domain registry = domainRepo
|
||||||
|
.findByDomainKey(REGISTRY_DOMAIN);
|
||||||
|
if (categoryRepo.findByPath(registry, confName) == null) {
|
||||||
return conf;
|
return conf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -690,8 +365,8 @@ public class ConfigurationManager {
|
||||||
confClass.getName(),
|
confClass.getName(),
|
||||||
getSettingName(field));
|
getSettingName(field));
|
||||||
final Class<?> settingType = field.getType();
|
final Class<?> settingType = field.getType();
|
||||||
final AbstractSetting<?> setting = findSetting(settingPath,
|
final AbstractSetting<?> setting = settingManager.findSetting(
|
||||||
settingType);
|
settingPath, settingType);
|
||||||
if (setting != null) {
|
if (setting != null) {
|
||||||
try {
|
try {
|
||||||
LOGGER.debug("Setting \"{}\" found. Value: %s",
|
LOGGER.debug("Setting \"{}\" found. Value: %s",
|
||||||
|
|
@ -717,7 +392,7 @@ public class ConfigurationManager {
|
||||||
configuration.getClass().getName());
|
configuration.getClass().getName());
|
||||||
final String categoryPath = configuration.getClass().getName();
|
final String categoryPath = configuration.getClass().getName();
|
||||||
final String[] tokens = categoryPath.split("\\.");
|
final String[] tokens = categoryPath.split("\\.");
|
||||||
final Domain registry = domainRepository
|
final Domain registry = domainRepo
|
||||||
.findByDomainKey(REGISTRY_DOMAIN);
|
.findByDomainKey(REGISTRY_DOMAIN);
|
||||||
|
|
||||||
final Category[] categories = new Category[tokens.length];
|
final Category[] categories = new Category[tokens.length];
|
||||||
|
|
@ -729,8 +404,8 @@ public class ConfigurationManager {
|
||||||
LOGGER.debug("#findCategoryForNewSetting: "
|
LOGGER.debug("#findCategoryForNewSetting: "
|
||||||
+ "Checking if category \"{}\" exists.",
|
+ "Checking if category \"{}\" exists.",
|
||||||
path);
|
path);
|
||||||
final Category category = categoryRepository.findByPath(registry,
|
final Category category = categoryRepo.findByPath(registry,
|
||||||
path);
|
path);
|
||||||
if (category == null) {
|
if (category == null) {
|
||||||
LOGGER.debug("#findCategoryForNewSetting: "
|
LOGGER.debug("#findCategoryForNewSetting: "
|
||||||
+ "Category \"{}\" does not exist.",
|
+ "Category \"{}\" does not exist.",
|
||||||
|
|
@ -794,7 +469,7 @@ public class ConfigurationManager {
|
||||||
final Category category = new Category();
|
final Category category = new Category();
|
||||||
category.setName(name);
|
category.setName(name);
|
||||||
category.setDisplayName(name);
|
category.setDisplayName(name);
|
||||||
categoryRepository.save(category);
|
categoryRepo.save(category);
|
||||||
entityManager.flush();
|
entityManager.flush();
|
||||||
categoryManager.addSubCategoryToCategory(category, parent);
|
categoryManager.addSubCategoryToCategory(category, parent);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,85 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2016 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.configuration;
|
||||||
|
|
||||||
|
import org.libreccm.l10n.LocalizedString;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import javax.enterprise.context.RequestScoped;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper class for converting values to settings.
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
|
*/
|
||||||
|
@RequestScoped
|
||||||
|
class SettingConverter {
|
||||||
|
|
||||||
|
private final Map<String, Class<? extends AbstractSetting<?>>> typeMap;
|
||||||
|
|
||||||
|
public SettingConverter() {
|
||||||
|
typeMap = new HashMap<>();
|
||||||
|
typeMap.put(BigDecimal.class.getName(), BigDecimalSetting.class);
|
||||||
|
typeMap.put(Boolean.class.getName(), BooleanSetting.class);
|
||||||
|
typeMap.put(Double.class.getName(), DoubleSetting.class);
|
||||||
|
typeMap.put(List.class.getName(), StringListSetting.class);
|
||||||
|
typeMap.put(LocalizedString.class.getName(),
|
||||||
|
LocalizedStringSetting.class);
|
||||||
|
typeMap.put(Long.class.getName(), LongSetting.class);
|
||||||
|
typeMap.put(Set.class.getName(), EnumSetting.class);
|
||||||
|
typeMap.put(String.class.getName(), StringSetting.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a setting instance of a specific value type.
|
||||||
|
*
|
||||||
|
* @param <T> Type variable.
|
||||||
|
* @param valueType The type of the value of the setting to create.
|
||||||
|
*
|
||||||
|
* @return An setting instance of the provided value type.
|
||||||
|
*
|
||||||
|
* @throws IllegalArgumentException If there is not setting type for the
|
||||||
|
* provided value type.
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
<T> AbstractSetting<T> createSettingForValueType(final Class<T> valueType) {
|
||||||
|
|
||||||
|
final String valueTypeName = valueType.getName();
|
||||||
|
final Class<? extends AbstractSetting<?>> clazz = typeMap.get(
|
||||||
|
valueTypeName);
|
||||||
|
|
||||||
|
if (clazz == null) {
|
||||||
|
throw new IllegalArgumentException(String.format(
|
||||||
|
"No setting type for value type \"%s\".", valueTypeName));
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
return (AbstractSetting<T>) clazz.newInstance();
|
||||||
|
} catch (InstantiationException | IllegalAccessException ex) {
|
||||||
|
throw new IllegalStateException(
|
||||||
|
"Failed to create setting instance.", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,272 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2016 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.configuration;
|
||||||
|
|
||||||
|
import static org.libreccm.configuration.ConfigurationConstants.*;
|
||||||
|
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.libreccm.categorization.Categorization;
|
||||||
|
import org.libreccm.categorization.Category;
|
||||||
|
import org.libreccm.categorization.CategoryRepository;
|
||||||
|
import org.libreccm.categorization.Domain;
|
||||||
|
import org.libreccm.categorization.DomainRepository;
|
||||||
|
import org.libreccm.core.CcmObject;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
import javax.enterprise.context.RequestScoped;
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.persistence.EntityManager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Manages settings in the registry. Normally there should be no need to use
|
||||||
|
* this class directly because the {@link ConfigurationManager} provide the same
|
||||||
|
* public methods for accessing settings than this class. The purpose of this
|
||||||
|
* class is only to separate the logic for managing settings from the logic for
|
||||||
|
* managing configuration classes and to reduce the complexity of the
|
||||||
|
* {@link ConfigurationManager} class
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
|
*/
|
||||||
|
@RequestScoped
|
||||||
|
public class SettingManager {
|
||||||
|
|
||||||
|
private static final Logger LOGGER = LogManager.getLogger(
|
||||||
|
SettingManager.class);
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private CategoryRepository categoryRepo;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private DomainRepository domainRepo;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private EntityManager entityManager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a {@link SettingInfo} instance for a setting.
|
||||||
|
*
|
||||||
|
* @param configuration The configuration class to which the settings
|
||||||
|
* belongs.
|
||||||
|
* @param name The name of the setting for which the
|
||||||
|
* {@link SettingInfo} is generated.
|
||||||
|
*
|
||||||
|
* @return The {@link SettingInfo} for the provided configuration class.
|
||||||
|
*/
|
||||||
|
@SuppressWarnings({"PMD.NPathComplexity",
|
||||||
|
"PMD.CyclomaticComplexity",
|
||||||
|
"PMD.StandardCyclomaticComplexity"})
|
||||||
|
public SettingInfo getSettingInfo(final Class<?> configuration,
|
||||||
|
final String name) {
|
||||||
|
if (configuration == null) {
|
||||||
|
throw new IllegalArgumentException("Configuration can't be null");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (configuration.getAnnotation(Configuration.class) == null) {
|
||||||
|
throw new IllegalArgumentException(String.format(
|
||||||
|
"The class \"%s\" of the provided object is not annotated "
|
||||||
|
+ "with \"%s\".",
|
||||||
|
configuration.getClass().getName(),
|
||||||
|
Configuration.class.getName()));
|
||||||
|
}
|
||||||
|
|
||||||
|
// final Configuration confAnnotation = configuration.getAnnotation(
|
||||||
|
// Configuration.class);
|
||||||
|
// final String descBundle;
|
||||||
|
// if (confAnnotation.descBundle() == null
|
||||||
|
// || confAnnotation.descBundle().isEmpty()) {
|
||||||
|
// descBundle = String.join("",
|
||||||
|
// configuration.getClass().getName(),
|
||||||
|
// "Description");
|
||||||
|
// } else {
|
||||||
|
// descBundle = confAnnotation.descBundle();
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
final Field field;
|
||||||
|
try {
|
||||||
|
field = configuration.getDeclaredField(name);
|
||||||
|
} catch (SecurityException | NoSuchFieldException ex) {
|
||||||
|
LOGGER.warn(String.format(
|
||||||
|
"Failed to generate SettingInfo for field \"%s\" of "
|
||||||
|
+ "configuration \"%s\". Ignoring field.",
|
||||||
|
configuration.getClass().getName(),
|
||||||
|
name),
|
||||||
|
ex);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (field.getAnnotation(Setting.class) == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
final Setting settingAnnotation = field.getAnnotation(Setting.class);
|
||||||
|
final SettingInfo settingInfo = new SettingInfo();
|
||||||
|
if (settingAnnotation.name() == null
|
||||||
|
|| settingAnnotation.name().isEmpty()) {
|
||||||
|
settingInfo.setName(field.getName());
|
||||||
|
} else {
|
||||||
|
settingInfo.setName(settingAnnotation.name());
|
||||||
|
}
|
||||||
|
|
||||||
|
settingInfo.setValueType(field.getType().getName());
|
||||||
|
|
||||||
|
try {
|
||||||
|
final Object conf = configuration.newInstance();
|
||||||
|
settingInfo.setDefaultValue(field.get(conf).toString());
|
||||||
|
} catch (InstantiationException | IllegalAccessException ex) {
|
||||||
|
LOGGER.warn(String.format("Failed to create instance of \"%s\" to "
|
||||||
|
+ "get default values.",
|
||||||
|
configuration.getName()),
|
||||||
|
ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
settingInfo.setConfClass(configuration.getName());
|
||||||
|
settingInfo.setDescBundle(getDescBundle(configuration));
|
||||||
|
|
||||||
|
if (settingAnnotation.labelKey() == null
|
||||||
|
|| settingAnnotation.labelKey().isEmpty()) {
|
||||||
|
settingInfo.setLabelKey(String.join(".", field.getName(),
|
||||||
|
"label"));
|
||||||
|
} else {
|
||||||
|
settingInfo.setLabelKey(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (settingAnnotation.descKey() == null
|
||||||
|
|| settingAnnotation.descKey().isEmpty()) {
|
||||||
|
settingInfo.setDescKey(String.join(".",
|
||||||
|
field.getName(),
|
||||||
|
"descripotion"));
|
||||||
|
} else {
|
||||||
|
settingInfo.setDescKey(settingAnnotation.descKey());
|
||||||
|
}
|
||||||
|
|
||||||
|
return settingInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A low level method for finding a setting in the registry.
|
||||||
|
*
|
||||||
|
* @param <T> Type of the value of the setting
|
||||||
|
* @param name The fully qualified name of the setting.
|
||||||
|
* @param clazz The class of the setting.
|
||||||
|
*
|
||||||
|
* @return The requested setting if it exists in the registry, {@code null}
|
||||||
|
* otherwise.
|
||||||
|
*/
|
||||||
|
public <T> AbstractSetting<T> findSetting(final String name,
|
||||||
|
final Class<T> clazz) {
|
||||||
|
LOGGER.debug(String.format(
|
||||||
|
"Trying to find setting \"%s\" of type \"%s\"",
|
||||||
|
name,
|
||||||
|
clazz.getName()));
|
||||||
|
final String[] tokens = name.split("\\.");
|
||||||
|
LOGGER.debug(String.format("Setting name \"%s\" has %d tokens.",
|
||||||
|
name,
|
||||||
|
tokens.length));
|
||||||
|
final String[] categoryTokens = Arrays.copyOfRange(tokens,
|
||||||
|
0,
|
||||||
|
tokens.length - 1);
|
||||||
|
final String categoryPath = String.join(".", categoryTokens);
|
||||||
|
LOGGER.debug(String.format("categoryPath for setting is \"%s\".",
|
||||||
|
categoryPath));
|
||||||
|
|
||||||
|
final Domain registry = domainRepo
|
||||||
|
.findByDomainKey(REGISTRY_DOMAIN);
|
||||||
|
final Category category = categoryRepo.findByPath(registry,
|
||||||
|
categoryPath);
|
||||||
|
if (category == null) {
|
||||||
|
LOGGER.warn(String.format(String.format(
|
||||||
|
"Category \"%s\" for setting \"%s\" not found.",
|
||||||
|
categoryPath,
|
||||||
|
name)));
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOGGER.debug(String.format("Category has %d objects. Filtering.",
|
||||||
|
category.getObjects().size()));
|
||||||
|
final Optional<Categorization> result = category
|
||||||
|
.getObjects()
|
||||||
|
.stream()
|
||||||
|
.filter((Categorization c)
|
||||||
|
-> c.getCategorizedObject() instanceof AbstractSetting)
|
||||||
|
.filter((Categorization c)
|
||||||
|
-> ((AbstractSetting<?>) c.getCategorizedObject())
|
||||||
|
.getName()
|
||||||
|
.equals(tokens[tokens.length - 1]))
|
||||||
|
.findFirst();
|
||||||
|
|
||||||
|
if (result.isPresent()) {
|
||||||
|
final CcmObject object = result.get().getCategorizedObject();
|
||||||
|
final AbstractSetting<?> entry = (AbstractSetting<?>) object;
|
||||||
|
|
||||||
|
if (clazz.isInstance(entry.getValue())) {
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
final AbstractSetting<T> resultEntry
|
||||||
|
= (AbstractSetting<T>) entry;
|
||||||
|
return resultEntry;
|
||||||
|
} else {
|
||||||
|
LOGGER.warn(String.format("Setting \"%s\" found but is not of "
|
||||||
|
+ "the requested type \"%s\".",
|
||||||
|
name,
|
||||||
|
clazz.getName()));
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
LOGGER.warn(String.format(
|
||||||
|
"Setting \"%s\" was not found in category \"%s\".",
|
||||||
|
name,
|
||||||
|
categoryPath));
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Low level method of saving a setting.
|
||||||
|
*
|
||||||
|
* @param setting The setting to save.
|
||||||
|
*/
|
||||||
|
public void saveSetting(final AbstractSetting<?> setting) {
|
||||||
|
if (setting.getObjectId() == 0) {
|
||||||
|
entityManager.persist(setting);
|
||||||
|
} else {
|
||||||
|
entityManager.merge(setting);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getDescBundle(final Class<?> configuration) {
|
||||||
|
final Configuration confAnnotation = configuration.getAnnotation(
|
||||||
|
Configuration.class);
|
||||||
|
if (confAnnotation.descBundle() == null
|
||||||
|
|| confAnnotation.descBundle().isEmpty()) {
|
||||||
|
return String.join("",
|
||||||
|
configuration.getClass().getName(),
|
||||||
|
"Description");
|
||||||
|
} else {
|
||||||
|
return confAnnotation.descBundle();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue