package org.oddjob.values.properties;
import java.util.LinkedList;
import java.util.Properties;
import java.util.Set;
/**
* Track system properties set.
*
* @author rob
*
*/
public class SystemPropertyStack {
private static final LinkedList<Token> tokens =
new LinkedList<>();
public static synchronized Token addProperties(Properties properties) {
Token token = new Token(properties);
tokens.push(token);
return token;
}
public static synchronized void removeProperties(Token token) {
if (tokens.peek() == token) {
token.restore();
tokens.pop();
}
else {
Token next = tokens.get(tokens.indexOf(token) - 1);
next.acceptFrom(token);
tokens.remove(token);
}
}
public static class Token {
private final Set<String> propertyNames;
private final Properties originals = new Properties();
Token(Properties properties) {
this.propertyNames = properties.stringPropertyNames();
for (String name : propertyNames) {
String existing = System.getProperty(name);
if (existing != null) {
originals.put(name, existing);
}
System.setProperty(name, properties.getProperty(name));
}
}
void acceptFrom(Token previous) {
for (String name : previous.propertyNames) {
String value = previous.originals.getProperty(name);
if (propertyNames.contains(name)) {
if (value == null) {
originals.remove(name);
}
else {
originals.put(name, value);
}
}
else {
if (value == null) {
System.getProperties().remove(name);
}
else {
System.setProperty(name, value);
}
}
}
}
void restore() {
for (String name : propertyNames) {
String value = originals.getProperty(name);
if (value == null) {
System.getProperties().remove(name);
}
else {
System.setProperty(name, value);
}
}
}
}
}