package de.tum.in.i22.uc.cm.settings;
import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import de.tum.in.i22.uc.cm.datatypes.basic.DataBasic;
import de.tum.in.i22.uc.cm.datatypes.basic.NameBasic;
import de.tum.in.i22.uc.cm.datatypes.interfaces.IData;
import de.tum.in.i22.uc.cm.datatypes.interfaces.IName;
import de.tum.in.i22.uc.cm.distribution.ECommunicationProtocol;
import de.tum.in.i22.uc.cm.distribution.EDistributionStrategy;
import de.tum.in.i22.uc.cm.distribution.IPLocation;
import de.tum.in.i22.uc.cm.distribution.LocalLocation;
import de.tum.in.i22.uc.cm.distribution.Location;
import de.tum.in.i22.uc.cm.distribution.Location.ELocation;
import de.tum.in.i22.uc.cm.pip.EInformationFlowModel;
/**
*
* @author Florian Kelbert Settings are read from the specified properties file.
* If no file is specified, file "uc.properties" is used.
*
*/
public class Settings extends SettingsLoader {
private static Logger _logger = LoggerFactory.getLogger(Settings.class);
private static Settings _instance = null;
private static String _propertiesFile = "uc.properties";
private static final String PROP_NAME_pdpListenerPort = "pdpListenerPort";
private static final String PROP_NAME_pmpListenerPort = "pmpListenerPort";
private static final String PROP_NAME_pipListenerPort = "pipListenerPort";
private static final String PROP_NAME_anyListenerPort = "anyListenerPort";
private static final String PROP_NAME_pxpListenerPort = "pxpListenerPort";
private static final String PROP_NAME_anyListenerEnabled = "anyListenerEnabled";
private static final String PROP_NAME_pdpLocation = "pdpLocation";
private static final String PROP_NAME_pipLocation = "pipLocation";
private static final String PROP_NAME_pmpLocation = "pmpLocation";
private static final String PROP_NAME_pipEnabledInformationFlowModels = "pipEnabledInformationFlowModels";
private static final String PROP_NAME_pipEventHandlerSuffix = "pipEventHandlerSuffix";
private static final String PROP_NAME_pipEventHandlerPackage = "pipEventHandlerPackage";
private static final String PROP_NAME_pipInitializerEvent = "pipInitializerEvent";
private static final String PROP_NAME_pipPersistenceDirectory = "pipPersistenceDirectory";
private static final String PROP_NAME_pipPrintAfterUpdate = "pipPrintAfterUpdate";
private static final String PROP_NAME_separator1 = "separator1";
private static final String PROP_NAME_separator2 = "separator2";
private static final String PROP_NAME_pipInitialRepresentationSeparator1 = "pipInitialRepresentationSeparator1";
private static final String PROP_NAME_pipInitialRepresentationSeparator2 = "pipInitialRepresentationSeparator2";
private static final String PROP_NAME_prefixSeparator = "prefixSeparator";
private static final String PROP_NAME_pepParameterKey = "pep";
private static final String PROP_NAME_allowImpliesActualParameterKey = "allowImpliesActual";
private static final String PROP_NAME_pipInitialRepresentations = "pipInitialRepresentations";
private static final String PROP_NAME_communicationProtocol = "communicationProtocol";
private static final String PROP_NAME_distributionStrategy = "distributionStrategy";
private static final String PROP_NAME_pipDistributionMaxConnections = "pipDistributionMaxConnections";
private static final String PROP_NAME_pdpDistributionMaxConnections = "pdpDistributionMaxConnections";
private static final String PROP_NAME_pmpDistributionMaxConnections = "pmpDistributionMaxConnections";
private static final String PROP_NAME_connectionAttemptInterval = "connectionAttemptInterval";
private static final String PROP_NAME_starEvent = "starEvent";
private static final String PROP_NAME_scopeDelimiterName = "scopeDelimiterName";
private static final String PROP_NAME_scopeOpenDelimiter = "scopeOpenDelimiter";
private static final String PROP_NAME_scopeCloseDelimiter = "scopeCloseDelimiter";
private static final String PROP_NAME_scopeDirectionName = "scopeDirectionName";
private static final String PROP_NAME_scopeGenericInDirection = "scopeGenericInDirection";
private static final String PROP_NAME_scopeGenericOutDirection = "scopeGenericOutDirection";
private static final String PROP_NAME_showFullIFModel = "showFullIFModel";
private static final String PROP_NAME_policySpecificationStarDataClass = "policySpecificationStarDataClass";
private Settings() {
_settings = new HashMap<>();
try {
initProperties(_propertiesFile);
} catch (IOException e) {
_logger.warn("Unable to load properties file [" + _propertiesFile
+ "]. Using defaults.");
}
loadProperties();
}
public static void setPropertiesFile(String propertiesFile) {
boolean success = false;
if (_instance == null) {
synchronized (Settings.class) {
if (_instance == null) {
_propertiesFile = propertiesFile;
success = true;
}
}
}
if (success) {
_logger.warn("Must set properties file before getting the first Settings instance.");
}
}
public static Settings getInstance() {
/*
* This implementation may seem odd, overengineered, redundant, or all
* of it. Yet, it is the best way to implement a thread-safe singleton,
* cf.
* http://www.journaldev.com/171/thread-safety-in-java-singleton-classes
* -with-example-code -FK-
*/
if (_instance == null) {
synchronized (Settings.class) {
if (_instance == null)
_instance = new Settings();
}
}
return _instance;
}
private void loadProperties() {
loadSetting(PROP_NAME_pmpListenerPort, 21001);
loadSetting(PROP_NAME_pipListenerPort, 21002);
loadSetting(PROP_NAME_pdpListenerPort, 21003);
loadSetting(PROP_NAME_anyListenerPort, 21004);
loadSetting(PROP_NAME_pxpListenerPort, 30003);
loadSetting(PROP_NAME_anyListenerEnabled, true);
loadSetting(PROP_NAME_pdpLocation, LocalLocation.getInstance());
loadSetting(PROP_NAME_pipLocation, LocalLocation.getInstance());
loadSetting(PROP_NAME_pmpLocation, LocalLocation.getInstance());
loadSetting(PROP_NAME_pipEnabledInformationFlowModels,
"scope@structure");
loadSetting(PROP_NAME_pipEventHandlerSuffix, "EventHandler");
loadSetting(PROP_NAME_pipEventHandlerPackage,
"de.tum.in.i22.uc.pip.eventdef.");
loadSetting(PROP_NAME_pipInitializerEvent, "SchemaInitializer");
loadSetting(PROP_NAME_pipPersistenceDirectory, "pipdb");
loadSetting(PROP_NAME_pipPrintAfterUpdate, true);
loadSetting(PROP_NAME_separator1, "@");
loadSetting(PROP_NAME_separator2, "#");
loadSetting(PROP_NAME_pipInitialRepresentationSeparator1, ";");
loadSetting(PROP_NAME_pipInitialRepresentationSeparator2, ":");
loadSetting(PROP_NAME_prefixSeparator, "_");
loadSetting(PROP_NAME_pepParameterKey, "PEP");
loadSetting(PROP_NAME_allowImpliesActualParameterKey, "false");
loadSetting(PROP_NAME_pipInitialRepresentations,
new HashMap<IName, IData>() {
private static final long serialVersionUID = -2810488356921449504L;
{
put(new NameBasic("TEST_C"), new DataBasic("TEST_D"));
}
});
loadSetting(PROP_NAME_communicationProtocol,
ECommunicationProtocol.THRIFT, ECommunicationProtocol.class);
loadSetting(PROP_NAME_distributionStrategy, EDistributionStrategy.PUSH,
EDistributionStrategy.class);
loadSetting(PROP_NAME_pipDistributionMaxConnections, 5);
loadSetting(PROP_NAME_pdpDistributionMaxConnections, 5);
loadSetting(PROP_NAME_pmpDistributionMaxConnections, 5);
loadSetting(PROP_NAME_connectionAttemptInterval, 1000);
loadSetting(PROP_NAME_starEvent, "*");
loadSetting(PROP_NAME_scopeDelimiterName, "delimiter");
loadSetting(PROP_NAME_scopeOpenDelimiter, "start");
loadSetting(PROP_NAME_scopeCloseDelimiter, "end");
loadSetting(PROP_NAME_scopeDirectionName, "direction");
loadSetting(PROP_NAME_scopeGenericInDirection, "IN");
loadSetting(PROP_NAME_scopeGenericOutDirection, "OUT");
loadSetting(PROP_NAME_showFullIFModel, false);
loadSetting(PROP_NAME_policySpecificationStarDataClass, "*");
}
public Location loadSetting(String propName, Location defaultValue) {
Location loadedValue = defaultValue;
boolean success = false;
try {
if (_props != null) {
loadedValue = new IPLocation(_props.getProperty(propName));
if (loadedValue != null) {
success = true;
}
}
} catch (Exception e) {
}
return loadSettingFinalize(success, propName, loadedValue, defaultValue);
}
public <E extends Enum<E>> E loadSetting(String propName, E defaultValue,
Class<E> cls) {
E loadedValue = defaultValue;
boolean success = false;
try {
if (_props != null) {
loadedValue = E.valueOf(cls, (String) _props.get(propName));
if (loadedValue != null) {
success = true;
}
}
} catch (Exception e) {
success = false;
}
return loadSettingFinalize(success, propName, loadedValue, defaultValue);
}
/**
* Loads the initial representations for the Pip. They are expected to be in
* the format <ContainerName1>:<DataId1>;<ContainerName2>:<DataId2>; ...
*
* @param propName
* the property name
* @param defaultValue
* @return
*/
public Map<IName, IData> loadSetting(String propName,
Map<IName, IData> defaultValue) {
Map<IName, IData> loadedValue = new HashMap<>();
boolean success = false;
String stringRead = null;
try {
if (_props != null)
stringRead = (String) _props.get(propName);
} catch (Exception e) {
stringRead = null;
success = false;
}
if (stringRead != null && stringRead.length() > 0) {
// entries are divided by semicolon (;)
String[] entries = stringRead
.split(getPipInitialRepresentationSeparator1());
if (entries != null && entries.length > 0) {
for (String entry : entries) {
// each entry is divided by exactly one colon
// first part: container name; second part: data ID
String[] entryParts = entry
.split(getPipInitialRepresentationSeparator2());
if (entryParts != null && entryParts.length == 2) {
loadedValue.put(new NameBasic(entryParts[0]),
new DataBasic(entryParts[1]));
} else {
_logger.debug("Incorrect entry format: " + entry);
}
}
}
}
success = loadedValue.size() > 0;
return loadSettingFinalize(success, propName, loadedValue, defaultValue);
}
public String getAllowImpliesActualParameterKey() {
return PROP_NAME_allowImpliesActualParameterKey;
}
public String getPropertiesFileName() {
return _propertiesFile;
}
public int getPmpListenerPort() {
return getValue(PROP_NAME_pmpListenerPort);
}
public int getPipListenerPort() {
return getValue(PROP_NAME_pipListenerPort);
}
public int getPdpListenerPort() {
return getValue(PROP_NAME_pdpListenerPort);
}
public int getPxpListenerPort() {
return getValue(PROP_NAME_pxpListenerPort);
}
public int getAnyListenerPort() {
return getValue(PROP_NAME_anyListenerPort);
}
public boolean isPmpListenerEnabled() {
Location l = getValue(PROP_NAME_pmpLocation);
return ((l == null) ? false : (l.getLocation() == ELocation.LOCAL));
}
public boolean isPipListenerEnabled() {
Location l = getValue(PROP_NAME_pipLocation);
return ((l == null) ? false : (l.getLocation() == ELocation.LOCAL));
}
public boolean isPdpListenerEnabled() {
Location l = getValue(PROP_NAME_pdpLocation);
return ((l == null) ? false : (l.getLocation() == ELocation.LOCAL));
}
public boolean isAnyListenerEnabled() {
return getValue(PROP_NAME_anyListenerEnabled);
}
public EDistributionStrategy getDistributionStrategy() {
return getValue(PROP_NAME_distributionStrategy);
}
public String getPipEventHandlerPackage() {
return getValue(PROP_NAME_pipEventHandlerPackage);
}
public String getPipEventHandlerSuffix() {
return getValue(PROP_NAME_pipEventHandlerSuffix);
}
public Set<EInformationFlowModel> getEnabledInformationFlowModels() {
return EInformationFlowModel
.from((String) getValue(PROP_NAME_pipEnabledInformationFlowModels));
}
public Location getPdpLocation() {
return getValue(PROP_NAME_pdpLocation);
}
public Location getPipLocation() {
return getValue(PROP_NAME_pipLocation);
}
public Location getPmpLocation() {
return getValue(PROP_NAME_pmpLocation);
}
public String getPipInitializerEvent() {
return getValue(PROP_NAME_pipInitializerEvent);
}
public String getPipPersistenceDirectory() {
return getValue(PROP_NAME_pipPersistenceDirectory);
}
public boolean getPipPrintAfterUpdate() {
return getValue(PROP_NAME_pipPrintAfterUpdate);
}
public ECommunicationProtocol getCommunicationProtocol() {
return getValue(PROP_NAME_communicationProtocol);
}
@SuppressWarnings("unchecked")
public Map<IName, IData> getPipInitialRepresentations() {
return Collections
.unmodifiableMap((Map<IName, IData>) getValue(PROP_NAME_pipInitialRepresentations));
}
public int getPipDistributionMaxConnections() {
return getValue(PROP_NAME_pipDistributionMaxConnections);
}
public int getPdpDistributionMaxConnections() {
return getValue(PROP_NAME_pdpDistributionMaxConnections);
}
public int getPmpDistributionMaxConnections() {
return getValue(PROP_NAME_pmpDistributionMaxConnections);
}
public int getConnectionAttemptInterval() {
return getValue(PROP_NAME_connectionAttemptInterval);
}
public String getSeparator1() {
return getValue(PROP_NAME_separator1);
}
public String getSeparator2() {
return getValue(PROP_NAME_separator2);
}
public String getPrefixSeparator() {
return getValue(PROP_NAME_prefixSeparator);
}
public String getPep() {
return getValue(PROP_NAME_pepParameterKey);
}
public String getAllowImpliesActual() {
return getValue(PROP_NAME_allowImpliesActualParameterKey);
}
public String getPipInitialRepresentationSeparator1() {
return getValue(PROP_NAME_pipInitialRepresentationSeparator1);
}
public String getPipInitialRepresentationSeparator2() {
return getValue(PROP_NAME_pipInitialRepresentationSeparator2);
}
public String getStarEvent() {
return getValue(PROP_NAME_starEvent);
}
public String getScopeDelimiterName() {
return getValue(PROP_NAME_scopeDelimiterName);
}
public String getScopeOpenDelimiter() {
return getValue(PROP_NAME_scopeOpenDelimiter);
}
public String getScopeCloseDelimiter() {
return getValue(PROP_NAME_scopeCloseDelimiter);
}
public String getScopeDirectionName() {
return getValue(PROP_NAME_scopeDirectionName);
}
public String getScopeGenericInDirection() {
return getValue(PROP_NAME_scopeGenericInDirection);
}
public String getScopeGenericOutDirection() {
return getValue(PROP_NAME_scopeGenericOutDirection);
}
public boolean getShowFullIFModel() {
return getValue(PROP_NAME_showFullIFModel);
}
public String getPolicySpecificationStarDataClass() {
return getValue(PROP_NAME_policySpecificationStarDataClass);
}
}