package nl.tudelft.bw4t.client.startup;
import java.io.FileNotFoundException;
import java.net.URISyntaxException;
import java.util.HashMap;
import java.util.Map;
import javax.xml.bind.JAXBException;
import org.apache.log4j.BasicConfigurator;
import org.apache.log4j.Level;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import eis.iilang.Identifier;
import eis.iilang.Parameter;
import nl.tudelft.bw4t.client.environment.RemoteEnvironment;
/**
* Available init parameters and default values for {@link BW4TEnvironment}.
*/
public enum InitParam {
/** Our IP. Passed to server so server is able to find us with this IP. */
CLIENTIP("localhost"),
/** The port that we use. */
CLIENTPORT("2000"),
/** The IP address of the server. */
SERVERIP("localhost"),
/** The Port used by the server. */
SERVERPORT("8000"),
/** Number of agents that we have. */
AGENTCOUNT("0"),
/**
* Launch GUI for agent controlled entities showing their behaviour and
* percepts
*/
LAUNCHGUI("true"),
/** Number of human bots (is this to connect GUIs?) */
HUMANCOUNT("1"),
/**
* The java agent class to load when new entities appear.
*/
AGENTCLASS("nl.tudelft.bw4t.client.agent.BW4TAgent"),
/**
* are we connected with GOAL? This param should be auto detected, it will
* be set to false if the program is started from commandline.
*/
GOAL("true"),
/**
* The key we should try to use to kill the remote server.
*/
KILL(""),
/**
* The file from which the client reads the configuration.
*/
CONFIGFILE(""),
/**
* Forces the use of the human GUI with an GOAL agent to translate the
* commands
*/
GOALHUMAN("false"),
/** Name or filename of the map to use */
MAP(""),
/**
* Preferred speed. Empty -> null -> not set.
*/
SPEED(""),
/*
* /** The log4j log level to be used. Default to ERROR so that naive users
* at least see critical messages #3204. available values: OFF, FATAL,
* ERROR, WARN, INFODEBUG and ALL.
*/
LOG("ERROR");
private static final Logger LOGGER = Logger.getLogger(InitParam.class);
private String defaultvalue;
/**
* Store a referenc to the object that manages the parameters from the
* config file
*/
private static ConfigFile config;
/**
* Store the program-wide parameters given to the {@link RemoteEnvironment}.
*/
private static Map<String, Parameter> parameters = null;
/**
* @param def
* - The default value of the init parameter.
*/
InitParam(String def) {
defaultvalue = def;
}
public String getDefaultValue() {
return defaultvalue;
}
/**
* {@link #name()} but in lower case.
*
* @return Name in lower case.
*/
public String nameLower() {
return this.name().toLowerCase();
}
/**
* Retrieve the value of this InitParam EnumType.
*
* @return the value of the parameter or the default value.
*/
public String getValue() {
Parameter param = getParameter(this.nameLower());
if (param != null) {
return ((Identifier) param).getValue();
}
if (config != null) {
String result = config.getValue(this);
if (result != null) {
return result;
}
}
return getDefaultValue();
}
/**
* Get the integer value of this parameter
*
* @return the integer value of this value
* @see Integer#parseInt(String)
*/
public int getIntValue() {
return Integer.parseInt(getValue());
}
/**
* Get the boolean value of this parameter.
*
* @return true iff the string is equal to true
* @see Boolean#parseBoolean(String)
*/
public boolean getBoolValue() {
return Boolean.parseBoolean(getValue());
}
/**
* Set the program-wide parameters.
*
* @param params
* - The Map of parameters given to the {@link RemoteEnvironment}
*/
public static void setParameters(Map<String, Parameter> params) {
parameters = params;
config = null;
// set the global log level as indicated in params (or use default).
LogManager.getRootLogger().setLevel(Level.toLevel(InitParam.LOG.getValue()));
if (InitParam.GOAL.getBoolValue()) {
BasicConfigurator.configure();
}
final String cfile = CONFIGFILE.getValue();
if (!cfile.isEmpty()) {
LOGGER.info(String.format("Reading configuration file '%s'", cfile));
try {
config = new ConfigFile(cfile);
} catch (JAXBException | FileNotFoundException | URISyntaxException e) {
LOGGER.error(String.format("Unable to load configuration file: '%s'", cfile), e);
}
}
}
/**
* Get all program-wide parameters, with the actual values.
*
* @return The Map of parameters given to the {@link RemoteEnvironment}
*/
public static Map<String, Parameter> getParameters() {
Map<String, Parameter> ret = new HashMap<>();
for (InitParam p : values()) {
ret.put(p.nameLower(), new Identifier(p.getValue()));
LOGGER.info(p.nameLower() + " => " + p.getValue());
}
for (String k : parameters.keySet()) {
InitParam p = Enum.valueOf(InitParam.class, k.toUpperCase());
if (p == null) {
ret.put(k, parameters.get(k));
LOGGER.info(k + " => " + parameters.get(k));
}
}
return ret;
}
/**
* Filter out all the parameters for the server from the given set of
* parameters. We do this by removing all parameters that we can handle as
* client; the remaining ones must be server parameters.
*
* @return parameters for the server
*/
public static Map<String, Parameter> getServerParameters() {
Map<String, Parameter> serverparams = getParameters();
for (InitParam param : InitParam.values()) {
if (param == MAP && !MAP.getValue().isEmpty()) {
continue;
}
serverparams.remove(param.nameLower());
}
return serverparams;
}
/**
* Get the Parameter by name.
*
* @param name
* - The name of the parameter to be read.
* @return The parameter with the given name or {@code null} if not found.
*/
public static Parameter getParameter(String name) {
if (parameters == null) {
return null;
}
return parameters.get(name);
}
public void setDefaultValue(String defaultvalue) {
this.defaultvalue = defaultvalue;
}
public static ConfigFile getConfigFile() {
return config;
}
}