package rtt.core.manager.data;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import rtt.core.archive.configuration.Classpath;
import rtt.core.archive.configuration.Configuration;
import rtt.core.archive.configuration.Configurations;
import rtt.core.loader.ArchiveLoader;
import rtt.core.loader.fetching.SimpleFileFetching;
import rtt.core.utils.RTTLogging;
/**
* This Manager manages the processing of configurations.
*
* @author Christian Oelsner <C.Oelsner@gmail.com>
*/
public class ConfigurationManager extends AbstractDataManager<Configurations> {
/**
* This enumeration contains the result of the setConfiguration action of
* the {@link ConfigurationManager} indicating the actions which have been taken to the archive.
*
* @author Christian Oelsner <C.Oelsner@gmail.com>
* @see ConfigurationManager
* @see ConfigurationManager#setConfiguration(Configuration, boolean)
*/
public enum ConfigStatus {
/**
* A new configuration has been added.
*/
ADDED,
/**
* An existing configuration has been updated.
*/
UPDATED,
/**
* The configuration has been rejected.
*/
SKIPPED;
/**
* true, if a new initial node class was set.
*/
public boolean initialNodeSet = false;
/**
* A list containing all new entries to the class path
*/
public Set<String> newEntries = new TreeSet<String>();
/**
* A list containing all deleted entries of a class path
*/
public Set<String> deletedEntries = new TreeSet<String>();
}
public ConfigurationManager(ArchiveLoader loader) {
super(loader, new SimpleFileFetching("configs.xml", ""));
}
@Override
public Configurations doLoad() throws Exception {
return unmarshall(Configurations.class);
}
@Override
public void doSave(Configurations data) {
marshall(Configurations.class, data);
}
/**
* Sets a configuration to the archive.
* <p>
* If no configuration with the same name exists, the configuration will be
* added. If a configuration is already existing, the overwrite flag is used
* to decide what should be done.
* <p>
* A {@link ConfigStatus} element will indicate the result of the operation.
*
* @param newConfig
* the configuration, which should be set
* @param overwrite
* set true to overwrite configuration, if already existing
* @return a {@link ConfigStatus}, indicating the the changes to the archive
* @see Configuration
* @see ConfigStatus
*/
public ConfigStatus setConfiguration(Configuration newConfig, boolean overwrite) {
List<Configuration> configList = data.getConfiguration();
Configuration oldConfig = getConfiguration(newConfig.getName());
// old config exists, but should not be overwritten
if (oldConfig != null && overwrite == false) {
return ConfigStatus.SKIPPED;
}
if (configList.size() < 1) {
data.setDefault(newConfig.getName());
}
ConfigStatus state = null;
// no config exists, create new one
if (oldConfig == null) {
configList.add(newConfig);
state = ConfigStatus.ADDED;
String initialNodeClass = newConfig.getInitialNode();
state.initialNodeSet = initialNodeClass != null && !initialNodeClass.trim().isEmpty();
Classpath cPath = newConfig.getClasspath();
if (cPath != null) {
for (String entry : cPath.getPath()) {
state.newEntries.add(entry);
}
}
// old config exists, update the old one
} else {
state = ConfigStatus.UPDATED;
state.initialNodeSet = setInitialNode(oldConfig, newConfig.getInitialNode());
state.newEntries = addClasspathEntries(oldConfig, newConfig);
state.deletedEntries = removeClasspathEntries(oldConfig, newConfig);
// if nothing done, return skipped
if (!state.initialNodeSet
&& state.newEntries.isEmpty() && state.deletedEntries.isEmpty()) {
state = ConfigStatus.SKIPPED;
}
}
return state;
}
private boolean setInitialNode(Configuration config, String initialNode) {
if (config != null && initialNode != null) {
String oldClass = config.getInitialNode();
if (oldClass == null || oldClass.equals("")
|| !oldClass.equals(initialNode)) {
config.setInitialNode(initialNode);
return true;
}
}
return false;
}
private Set<String> addClasspathEntries(Configuration oldConfig, Configuration newConfig) {
Set<String> newPathEntries = new TreeSet<String>();
if (oldConfig != null && newConfig != null) {
Classpath newClasspath = newConfig.getClasspath();
if (newClasspath != null) {
for (String path : newClasspath.getPath()) {
if (addClasspathEntry(oldConfig, path)) {
newPathEntries.add(path);
}
}
}
}
return newPathEntries;
}
protected boolean addClasspathEntry(Configuration config, String entry) {
if (config != null) {
Classpath classpath = config.getClasspath();
if (classpath == null) {
classpath = new Classpath();
}
for (String path : classpath.getPath()) {
if (path.equals(entry)) {
return false;
}
}
return classpath.getPath().add(entry);
}
return false;
}
private Set<String> removeClasspathEntries(Configuration oldConfig, Configuration newConfig) {
Set<String> removedEntries = new TreeSet<String>();
if (oldConfig != null && newConfig != null) {
Classpath oldClasspath = oldConfig.getClasspath();
if (oldClasspath != null) {
for (String path : oldClasspath.getPath()) {
if (!hasClasspathEntry(newConfig, path)) {
removedEntries.add(path);
}
}
}
oldConfig.setClasspath(newConfig.getClasspath());
}
return removedEntries;
}
private boolean hasClasspathEntry(Configuration config, String value) {
if (config != null && config.getClasspath() != null) {
Classpath cPath = config.getClasspath();
if (cPath.getPath() != null) {
for (String path : cPath.getPath()) {
if (path != null && path.equals(value)) {
return true;
}
}
}
}
return false;
}
protected boolean removeClasspathEntry(Configuration config, String entry) {
if (config != null) {
int index = -1;
Classpath classpath = config.getClasspath();
if (classpath != null && classpath.getPath() != null) {
List<String> pathList = classpath.getPath();
for (int i = 0; i < pathList.size(); i++) {
if (pathList.get(i).equals(entry)) {
index = i;
}
}
if (index > -1) {
pathList.remove(index);
return true;
}
}
}
return false;
}
/**
* Returns a {@link Configuration} or {@code null} for the given name.
*
* @param configName
* the name of the configuration
* @return {@link Configuration} or {@code null}
* @see Configuration
*/
public Configuration getConfiguration(String name) {
List<Configuration> configList = data.getConfiguration();
for (Configuration config : configList) {
if (config.getName().equals(name)) {
return config;
}
}
return null;
}
/**
* Returns the default configuration of the archive.
*
* @return the default configuration
* @see Configuration
* @see #getConfiguration(String)
*/
public Configuration getDefaultConfig() {
return getConfiguration(data.getDefault());
}
/**
* Sets a new default configuration for the archive.
*
* @param configName
* name of the new default configuration
* @return true, if configuration has been set
* @see Configuration
*/
public boolean setDefaultConfig(String configName) {
// TODO auskommentiert, wegen ant task fehler (create archive,
// create config)
// Configuration config = getConfiguration(configName);
//
// if (config != null
// && !config.getName().equals(getDefaultConfig().getName())) {
// data.setDefault(configName);
// return true;
// }
// return false;
String defaultConfig = data.getDefault();
data.setDefault(configName);
if (defaultConfig == null || defaultConfig.equals(configName)) {
return false;
}
return true;
}
/**
* Prints informations about all configurations to the current logging.
*
* @see Configuration
*/
public void print() {
RTTLogging.info("DefaultConfiguration: " + data.getDefault());
for (Configuration c : data.getConfiguration()) {
RTTLogging.info("Config: " + c.getName());
if (c.getInitialNode() != null) {
RTTLogging.info("\tInitial Node: " + c.getInitialNode());
}
}
}
@Override
protected Configurations getEmptyData() {
return new Configurations();
}
/**
* Returns a list with all configurations.
*
* @return list with all configurations.
* @see Configuration
* @see Configurations#getConfiguration()
*/
public List<Configuration> getConfigurations() {
return data.getConfiguration();
}
}