package org.radargun.config;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
/**
* Describes one configuration of one product-config unit
*
* @author Radim Vansa <rvansa@redhat.com>
*/
public class Configuration implements Serializable {
public static final String DEFAULT_SERVICE = "default";
public final String name;
private List<Setup> setups = new ArrayList<>();
public Configuration(String name) {
if (name == null) throw new NullPointerException("Configuration name cannot be null");
this.name = name;
}
public String getName() {
return name;
}
public Setup addSetup(String base, String group, String plugin, String service, Map<String, Definition> propertyDefinitions, Map<String, Definition> vmArgs, Map<String, Definition> envs) {
for (Setup s : setups) {
if (s.group.equals(group)) {
throw new IllegalArgumentException("Setup for group '" + group + "' already set!");
}
}
Setup setup = new Setup(base, group, plugin, service, propertyDefinitions, vmArgs, envs);
setups.add(setup);
return setup;
}
public void addSetup(Setup setup) {
setups.add(setup);
}
public List<Setup> getSetups() {
return Collections.unmodifiableList(setups);
}
public Setup getSetup(String groupName) {
for (Setup s : setups) {
if (s.group.equals(groupName)) {
return s;
}
}
throw new IllegalArgumentException("No setup for group '" + groupName + "'");
}
public static class SetupBase implements Serializable {
protected final String base;
protected final Map<String, Definition> properties;
protected final Map<String, Definition> vmArgs;
protected final Map<String, Definition> envs;
public SetupBase(String base, Map<String, Definition> vmArgs, Map<String, Definition> properties, Map<String, Definition> envs) {
this.base = base;
this.vmArgs = vmArgs;
this.properties = properties;
this.envs = envs;
}
public Map<String, Definition> getProperties() {
return Collections.unmodifiableMap(properties);
}
public Map<String, Definition> getVmArgs() {
return vmArgs;
}
public Map<String, Definition> getEnvironment() {
return envs;
}
}
public class Setup extends SetupBase {
public final String group;
public final String plugin;
public final String service;
public Setup(String base, String group, String plugin, String service, Map<String, Definition> properties, Map<String, Definition> vmArgs, Map<String, Definition> envs) {
super(base, vmArgs, properties, envs);
this.plugin = plugin;
this.service = service;
this.group = group;
}
public Configuration getConfiguration() {
return Configuration.this;
}
public Setup applyTemplates(Map<String, SetupBase> templates) {
if (base == null) {
return this;
}
List<SetupBase> lineage = new ArrayList<>();
lineage.add(this);
SetupBase origin = this;
do {
SetupBase template = templates.get(origin.base);
if (template == null) {
throw new IllegalArgumentException("Template '" + origin.base + "' does not exist!");
}
lineage.add(template);
origin = template;
} while (origin.base != null);
Map<String, Definition> newProperties = merge(lineage, setupBase -> setupBase.properties);
Map<String, Definition> newVmArgs = merge(lineage, setupBase -> setupBase.vmArgs);
Map<String, Definition> newEnvs = merge(lineage, setupBase -> setupBase.envs);
return new Setup(null, group, plugin, service, newProperties, newVmArgs, newEnvs);
}
}
private static Map<String, Definition> merge(List<SetupBase> lineage, Function<SetupBase, Map<String, Definition>> selector) {
Map<String, Definition> definitions = new HashMap<>();
for (int i = lineage.size() - 1; i >= 0; --i) {
selector.apply(lineage.get(i)).forEach((name, definition) -> {
Definition prev = definitions.get(name);
definitions.put(name, prev == null ? definition : prev.apply(definition));
});
}
return definitions;
}
}