// This software is released into the Public Domain. See copying.txt for details.
package org.openstreetmap.osmosis.core.pipeline.common;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashSet;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.TimeZone;
import org.openstreetmap.osmosis.core.OsmosisRuntimeException;
/**
* All task implementations require a corresponding task manager factory. This
* task manager factory is responsible for instantiating a task based upon
* command line arguments, and instantiating a task manager to manage the task
* within a pipeline. The factories are singleton instances registered globally
* and re-used for every task to be created.
*
* @author Brett Henderson
*/
public abstract class TaskManagerFactory {
private static final String DATE_FORMAT = "yyyy-MM-dd_HH:mm:ss";
private static final Locale DATE_LOCALE = Locale.US;
/**
* This stores the task options that have been accessed during task
* configuration. Any unused options are typically misspelt options that
* should raise an error. Minor overkill but this is stored as a thread
* local to ensure multiple threads can access a factory safely.
*/
private ThreadLocal<Set<String>> accessedTaskOptions;
/**
* Creates a new instance.
*/
protected TaskManagerFactory() {
accessedTaskOptions = new ThreadLocal<Set<String>>();
}
/**
* Create a new task manager containing a task instance.
*
* @param taskConfig
* Contains all information required to instantiate and configure
* the task.
* @return The newly created task manager.
*/
public TaskManager createTaskManager(TaskConfiguration taskConfig) {
TaskManager taskManager;
// Create a new accessed task options store.
accessedTaskOptions.set(new HashSet<String>());
taskManager = createTaskManagerImpl(taskConfig);
for (String argName : taskConfig.getConfigArgs().keySet()) {
if (!accessedTaskOptions.get().contains(argName)) {
throw new OsmosisRuntimeException(
"Argument " + argName + " for task " + taskConfig.getId() + " was not recognised.");
}
}
// Clear the accessed task options.
accessedTaskOptions.set(null);
return taskManager;
}
/**
* Create a new task manager containing a task instance.
*
* @param taskConfig
* Contains all information required to instantiate and configure
* the task.
* @return The newly created task manager.
*/
protected abstract TaskManager createTaskManagerImpl(TaskConfiguration taskConfig);
/**
* Checks if the specified argument has been supplied.
*
* @param taskConfig
* Contains all information required to instantiate and configure
* the task.
* @param argName
* The name of the argument.
* @return True if the argument has been supplied.
*/
protected boolean doesArgumentExist(TaskConfiguration taskConfig, String argName) {
return taskConfig.getConfigArgs().containsKey(argName);
}
/**
* Utility method for retrieving the default argument for the task as a String.
*
* @param taskConfig
* Contains all information required to instantiate and configure
* the task.
* @param defaultValue
* The default value of the argument if not value is available.
* @return The value of the argument.
*/
protected String getDefaultStringArgument(TaskConfiguration taskConfig, String defaultValue) {
if (taskConfig.getDefaultArg() != null) {
return taskConfig.getDefaultArg();
} else {
return defaultValue;
}
}
/**
* Utility method for retrieving a String argument value from a Map of task
* arguments.
*
* @param taskConfig
* Contains all information required to instantiate and configure
* the task.
* @param argName
* The name of the argument.
* @return The value of the argument.
*/
protected String getStringArgument(TaskConfiguration taskConfig, String argName) {
Map<String, String> configArgs;
accessedTaskOptions.get().add(argName);
configArgs = taskConfig.getConfigArgs();
if (configArgs.containsKey(argName)) {
return configArgs.get(argName);
} else {
throw new OsmosisRuntimeException(
"Argument " + argName
+ " for task " + taskConfig.getId() + " does not exist.");
}
}
/**
* Utility method for retrieving a String argument value from a Map of task
* arguments.
*
* @param taskConfig
* Contains all information required to instantiate and configure
* the task.
* @param argName
* The name of the argument.
* @param defaultValue
* The default value of the argument if not value is available.
* @return The value of the argument.
*/
protected String getStringArgument(TaskConfiguration taskConfig, String argName, String defaultValue) {
Map<String, String> configArgs;
accessedTaskOptions.get().add(argName);
configArgs = taskConfig.getConfigArgs();
if (configArgs.containsKey(argName)) {
return configArgs.get(argName);
} else {
return defaultValue;
}
}
/**
* Utility method for retrieving the default argument for the task as an integer.
*
* @param taskConfig
* Contains all information required to instantiate and configure
* the task.
* @param defaultValue
* The default value of the argument if not value is available.
* @return The value of the argument.
*/
protected int getDefaultIntegerArgument(TaskConfiguration taskConfig, int defaultValue) {
String defaultArg;
defaultArg = taskConfig.getDefaultArg();
if (defaultArg != null) {
try {
return Integer.parseInt(defaultArg);
} catch (NumberFormatException e) {
throw new OsmosisRuntimeException(
"Default argument for task " + taskConfig.getId()
+ " must be an integer number.", e);
}
} else {
return defaultValue;
}
}
/**
* Utility method for retrieving an integer argument value from a Map of
* task arguments.
*
* @param taskConfig
* Contains all information required to instantiate and configure
* the task.
* @param argName
* The name of the argument.
* @return The value of the argument.
*/
protected int getIntegerArgument(TaskConfiguration taskConfig, String argName) {
Map<String, String> configArgs;
accessedTaskOptions.get().add(argName);
configArgs = taskConfig.getConfigArgs();
if (configArgs.containsKey(argName)) {
try {
return Integer.parseInt(configArgs.get(argName));
} catch (NumberFormatException e) {
throw new OsmosisRuntimeException(
"Argument " + argName + " for task " + taskConfig.getId()
+ " must be an integer number.", e);
}
} else {
throw new OsmosisRuntimeException(
"Argument " + argName + " for task " + taskConfig.getId() + " does not exist."
);
}
}
/**
* Utility method for retrieving an integer argument value from a Map of
* task arguments.
*
* @param taskConfig
* Contains all information required to instantiate and configure
* the task.
* @param argName
* The name of the argument.
* @param defaultValue
* The default value of the argument if not value is available.
* @return The value of the argument.
*/
protected int getIntegerArgument(TaskConfiguration taskConfig, String argName, int defaultValue) {
Map<String, String> configArgs;
accessedTaskOptions.get().add(argName);
configArgs = taskConfig.getConfigArgs();
if (configArgs.containsKey(argName)) {
try {
return Integer.parseInt(configArgs.get(argName));
} catch (NumberFormatException e) {
throw new OsmosisRuntimeException(
"Argument " + argName + " for task " + taskConfig.getId()
+ " must be an integer number.", e);
}
} else {
return defaultValue;
}
}
/**
* Utility method for retrieving a double argument value from a Map of task
* arguments.
*
* @param taskConfig
* Contains all information required to instantiate and configure
* the task.
* @param argName
* The name of the argument.
* @param defaultValue
* The default value of the argument if not value is available.
* @return The value of the argument.
*/
protected double getDoubleArgument(TaskConfiguration taskConfig,
String argName, double defaultValue) {
Map<String, String> configArgs;
accessedTaskOptions.get().add(argName);
configArgs = taskConfig.getConfigArgs();
if (configArgs.containsKey(argName)) {
try {
return Double.parseDouble(configArgs.get(argName));
} catch (NumberFormatException e) {
throw new OsmosisRuntimeException(
"Argument " + argName + " for task " + taskConfig.getId()
+ " must be a decimal number.", e);
}
} else {
return defaultValue;
}
}
/**
* Utility method for retrieving a date argument value from a Map of task
* arguments.
*
* @param taskConfig
* Contains all information required to instantiate and configure
* the task.
* @param argName
* The name of the argument.
* @param defaultValue
* The default value of the argument if not value is available.
* @return The value of the argument.
*/
protected Date getDateArgument(TaskConfiguration taskConfig,
String argName, Date defaultValue) {
Map<String, String> configArgs;
accessedTaskOptions.get().add(argName);
configArgs = taskConfig.getConfigArgs();
if (configArgs.containsKey(argName)) {
try {
SimpleDateFormat dateFormat;
dateFormat = new SimpleDateFormat(DATE_FORMAT, DATE_LOCALE);
return dateFormat.parse(configArgs.get(argName));
} catch (ParseException e) {
throw new OsmosisRuntimeException(
"Argument " + argName + " for task " + taskConfig.getId()
+ " must be a date in format " + DATE_FORMAT + ".", e);
}
} else {
return defaultValue;
}
}
/**
* Utility method for retrieving a date argument value from a Map of task
* arguments.
*
* @param taskConfig
* Contains all information required to instantiate and configure
* the task.
* @param argName
* The name of the argument.
* @param timeZone
* The time zone to parse the date in.
* @return The value of the argument.
*/
protected Date getDateArgument(TaskConfiguration taskConfig,
String argName, TimeZone timeZone) {
Map<String, String> configArgs;
accessedTaskOptions.get().add(argName);
configArgs = taskConfig.getConfigArgs();
if (configArgs.containsKey(argName)) {
try {
SimpleDateFormat dateFormat;
dateFormat = new SimpleDateFormat(DATE_FORMAT, DATE_LOCALE);
dateFormat.setTimeZone(timeZone);
return dateFormat.parse(configArgs.get(argName));
} catch (ParseException e) {
throw new OsmosisRuntimeException(
"Argument " + argName + " for task " + taskConfig.getId()
+ " must be a date in format " + DATE_FORMAT + ".", e);
}
} else {
throw new OsmosisRuntimeException("Argument " + argName
+ " for task " + taskConfig.getId() + " does not exist.");
}
}
/**
* Utility method for retrieving a boolean argument value from a Map of task
* arguments.
*
* @param taskConfig
* Contains all information required to instantiate and configure
* the task.
* @param argName
* The name of the argument.
* @param defaultValue
* The default value of the argument if not value is available.
* @return The value of the argument.
*/
protected boolean getBooleanArgument(TaskConfiguration taskConfig,
String argName, boolean defaultValue) {
Map<String, String> configArgs;
accessedTaskOptions.get().add(argName);
configArgs = taskConfig.getConfigArgs();
if (configArgs.containsKey(argName)) {
String rawValue;
rawValue = configArgs.get(argName).toLowerCase();
if ("true".equals(rawValue) || "yes".equals(rawValue)) {
return true;
} else if ("false".equals(rawValue) || "no".equals(rawValue)) {
return false;
} else {
throw new OsmosisRuntimeException(
"Argument " + argName + " for task " + taskConfig.getId()
+ " must be one of yes, no, true or false.");
}
} else {
return defaultValue;
}
}
}