CCM NG/ccm-core: Improved performance for the configuration (reduced number DB-Queries for loading a configuration).
git-svn-id: https://svn.libreccm.org/ccm/ccm_ng@4583 8810af33-2d31-482b-a856-94f89814c4dfpull/2/head
parent
450945ae22
commit
004ee26153
|
|
@ -51,10 +51,15 @@ import static org.libreccm.core.CoreConstants.*;
|
||||||
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
|
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
|
||||||
@NamedQueries({
|
@NamedQueries({
|
||||||
@NamedQuery(
|
@NamedQuery(
|
||||||
name = "AbstractSetting.findByClassAndName",
|
name = "AbstractSetting.findAllForClass",
|
||||||
query = "SELECT s FROM AbstractSetting s "
|
query = "SELECT s FROM AbstractSetting s "
|
||||||
+ "WHERE configurationClass = :class "
|
+ "WHERE s.configurationClass = :class")
|
||||||
+ "AND name = :name")
|
,
|
||||||
|
@NamedQuery(
|
||||||
|
name = "AbstractSetting.findByClassAndName",
|
||||||
|
query = "SELECT s FROM AbstractSetting s "
|
||||||
|
+ "WHERE s.configurationClass = :class "
|
||||||
|
+ "AND s.name = :name")
|
||||||
})
|
})
|
||||||
public abstract class AbstractSetting<T> implements Serializable {
|
public abstract class AbstractSetting<T> implements Serializable {
|
||||||
|
|
||||||
|
|
@ -151,10 +156,10 @@ public abstract class AbstractSetting<T> implements Serializable {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Objects.equals(configurationClass, other.configurationClass)) {
|
if (!Objects.equals(configurationClass, other.getConfigurationClass())) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return Objects.equals(name, other.name);
|
return Objects.equals(name, other.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean canEqual(final Object obj) {
|
public boolean canEqual(final Object obj) {
|
||||||
|
|
@ -168,17 +173,17 @@ public abstract class AbstractSetting<T> implements Serializable {
|
||||||
|
|
||||||
public String toString(final String data) {
|
public String toString(final String data) {
|
||||||
return String.format(
|
return String.format(
|
||||||
"%s{ "
|
"%s{ "
|
||||||
+ "settingId = %d, "
|
+ "settingId = %d, "
|
||||||
+ "configurationClass = \"%s\" "
|
+ "configurationClass = \"%s\" "
|
||||||
+ "name = \"%s\" "
|
+ "name = \"%s\" "
|
||||||
+ "%s"
|
+ "%s"
|
||||||
+ " }",
|
+ " }",
|
||||||
super.toString(),
|
super.toString(),
|
||||||
settingId,
|
settingId,
|
||||||
configurationClass,
|
configurationClass,
|
||||||
name,
|
name,
|
||||||
data);
|
data);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,9 @@ import org.libreccm.security.AuthorizationRequired;
|
||||||
import org.libreccm.security.RequiresPrivilege;
|
import org.libreccm.security.RequiresPrivilege;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.ServiceLoader;
|
import java.util.ServiceLoader;
|
||||||
import java.util.SortedSet;
|
import java.util.SortedSet;
|
||||||
import java.util.TreeSet;
|
import java.util.TreeSet;
|
||||||
|
|
@ -57,6 +59,11 @@ public class ConfigurationManager {
|
||||||
@Inject
|
@Inject
|
||||||
private SettingConverter settingConverter;
|
private SettingConverter settingConverter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Map used to cache configuration during a request.
|
||||||
|
*/
|
||||||
|
private final Map<String, Object> confCache = new HashMap<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Finds all configuration classes listed by the installed modules.
|
* Finds all configuration classes listed by the installed modules.
|
||||||
*
|
*
|
||||||
|
|
@ -101,6 +108,7 @@ public class ConfigurationManager {
|
||||||
* @throws IllegalArgumentException if the provided class is not annotated
|
* @throws IllegalArgumentException if the provided class is not annotated
|
||||||
* with {@link Configuration}.
|
* with {@link Configuration}.
|
||||||
*/
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
public <T> T findConfiguration(final Class<T> confClass) {
|
public <T> T findConfiguration(final Class<T> confClass) {
|
||||||
if (confClass == null) {
|
if (confClass == null) {
|
||||||
throw new IllegalArgumentException("confClass can't be null");
|
throw new IllegalArgumentException("confClass can't be null");
|
||||||
|
|
@ -114,8 +122,16 @@ public class ConfigurationManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
final String confName = confClass.getName();
|
final String confName = confClass.getName();
|
||||||
|
// First check if we have already retrieved the requested configuration
|
||||||
return findConfiguration(confName, confClass);
|
// during the current request. If not retrieve the configuration and
|
||||||
|
// put it into the map.
|
||||||
|
if (confCache.containsKey(confName)) {
|
||||||
|
return (T) confCache.get(confName);
|
||||||
|
} else {
|
||||||
|
final T configuration = findConfiguration(confName, confClass);
|
||||||
|
confCache.put(confName, configuration);
|
||||||
|
return configuration;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -182,6 +198,13 @@ public class ConfigurationManager {
|
||||||
ex);
|
ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the configuration is cached remove the cached version.
|
||||||
|
*/
|
||||||
|
if (confCache.containsKey(configuration.getClass().getName())) {
|
||||||
|
confCache.remove(configuration.getClass().getName());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -326,6 +349,7 @@ 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.
|
||||||
*/
|
*/
|
||||||
|
@SuppressWarnings("rawtypes")
|
||||||
<T> T findConfiguration(final String confName, final Class<T> confClass) {
|
<T> T findConfiguration(final String confName, final Class<T> confClass) {
|
||||||
final T conf;
|
final T conf;
|
||||||
|
|
||||||
|
|
@ -339,6 +363,12 @@ public class ConfigurationManager {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final List<AbstractSetting> settingList = settingManager
|
||||||
|
.retrieveAllSettings(confName);
|
||||||
|
final Map<String, AbstractSetting> settings = settingList.stream()
|
||||||
|
.collect(Collectors.toMap(setting -> setting.getName(),
|
||||||
|
setting -> setting));
|
||||||
|
|
||||||
final Field[] fields = confClass.getDeclaredFields();
|
final Field[] fields = confClass.getDeclaredFields();
|
||||||
for (final Field field : fields) {
|
for (final Field field : fields) {
|
||||||
field.setAccessible(true);
|
field.setAccessible(true);
|
||||||
|
|
@ -348,17 +378,15 @@ public class ConfigurationManager {
|
||||||
|
|
||||||
final String settingName = getSettingName(field);
|
final String settingName = getSettingName(field);
|
||||||
|
|
||||||
final Class<?> settingType = field.getType();
|
if (settings.containsKey(settingName)) {
|
||||||
final AbstractSetting<?> setting = settingManager.findSetting(
|
final AbstractSetting<?> setting = settings.get(settingName);
|
||||||
confName, settingName, settingType);
|
|
||||||
if (setting != null) {
|
|
||||||
try {
|
try {
|
||||||
LOGGER.debug("Setting \"{}#{}\" found. Value: {}",
|
LOGGER.debug("Setting \"{}#{}\" found. Value: {}",
|
||||||
confName,
|
confName,
|
||||||
settingName,
|
settingName,
|
||||||
setting.getValue());
|
setting.getValue());
|
||||||
field.set(conf, setting.getValue());
|
field.set(conf, setting.getValue());
|
||||||
} catch (IllegalAccessException ex) {
|
} catch(IllegalAccessException ex) {
|
||||||
LOGGER.warn(
|
LOGGER.warn(
|
||||||
"Failed to set value of configuration class \"{}\". "
|
"Failed to set value of configuration class \"{}\". "
|
||||||
+ "Ignoring.",
|
+ "Ignoring.",
|
||||||
|
|
@ -366,6 +394,25 @@ public class ConfigurationManager {
|
||||||
ex);
|
ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//
|
||||||
|
// final Class<?> settingType = field.getType();
|
||||||
|
// final AbstractSetting<?> setting = settingManager.findSetting(
|
||||||
|
// confName, settingName, settingType);
|
||||||
|
// if (setting != null) {
|
||||||
|
// try {
|
||||||
|
// LOGGER.debug("Setting \"{}#{}\" found. Value: {}",
|
||||||
|
// confName,
|
||||||
|
// settingName,
|
||||||
|
// setting.getValue());
|
||||||
|
// field.set(conf, setting.getValue());
|
||||||
|
// } catch (IllegalAccessException ex) {
|
||||||
|
// LOGGER.warn(
|
||||||
|
// "Failed to set value of configuration class \"{}\". "
|
||||||
|
// + "Ignoring.",
|
||||||
|
// confClass.getName(),
|
||||||
|
// ex);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
return conf;
|
return conf;
|
||||||
|
|
|
||||||
|
|
@ -94,6 +94,17 @@ public class SettingManager {
|
||||||
return settings;
|
return settings;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<AbstractSetting> retrieveAllSettings(final String confName) {
|
||||||
|
Objects.requireNonNull(confName);
|
||||||
|
|
||||||
|
final TypedQuery<AbstractSetting> query = entityManager
|
||||||
|
.createNamedQuery("AbstractSetting.findAllForClass",
|
||||||
|
AbstractSetting.class);
|
||||||
|
query.setParameter("class", confName);
|
||||||
|
|
||||||
|
return query.getResultList();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a {@link SettingInfo} instance for a setting.
|
* Create a {@link SettingInfo} instance for a setting.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue