package mil.nga.giat.geowave.core.cli.prefix;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.Set;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.beust.jcommander.JCommander;
/**
* This class will translate a given set of ParameterDescription entries into a
* properties file or back given a JCommander translation map.
*/
public class JCommanderPropertiesTransformer
{
private static Logger LOGGER = LoggerFactory.getLogger(JCommanderPropertiesTransformer.class);
// The namespace is prepended to entries translated via
// this translator in the Properties object, or it is used
// to only retrieve properties that start with this
// namespace.
private final String propertyFormat;
private List<Object> objects = new ArrayList<Object>();
public JCommanderPropertiesTransformer(
String namespace ) {
if (namespace == null) {
propertyFormat = "%s";
}
else {
propertyFormat = String.format(
"%s.%s",
namespace,
"%s");
}
}
public JCommanderPropertiesTransformer() {
this(
null);
}
/**
* Add an object to be translated
*
* @param object
*/
public void addObject(
Object object ) {
objects.add(object);
}
/**
* Entries are needed to translate to/from the objects using the JCommander
* prefixes.
*
* @return
*/
private Collection<TranslationEntry> generateEntries() {
JCommanderPrefixTranslator translator = new JCommanderPrefixTranslator();
for (Object obj : objects) {
translator.addObject(obj);
}
JCommanderTranslationMap map = translator.translate();
return map.getEntries().values();
}
/**
* Take the options and translate them to a map.
*
* @param properties
*/
public void transformToMap(
Map<String, String> properties ) {
Properties props = new Properties();
transformToProperties(props);
for (String prop : props.stringPropertyNames()) {
properties.put(
prop,
props.getProperty(prop));
}
}
/**
* Take the options and translate them from a map.
*
* @param properties
*/
public void transformFromMap(
Map<String, String> properties ) {
Properties props = new Properties();
for (Entry<String, String> prop : properties.entrySet()) {
if (prop.getValue() != null) {
props.setProperty(
prop.getKey(),
prop.getValue());
}
}
transformFromProperties(props);
}
/**
* Take the given values in the translation map, and convert them to a
* properties list.
*
* @param toProperties
*/
public void transformToProperties(
Properties toProperties ) {
// Translate all fields.
for (TranslationEntry entry : generateEntries()) {
// Get the Properties name.
String propertyName = entry.getAsPropertyName();
propertyName = String.format(
propertyFormat,
propertyName);
// Get the value.
Object value = null;
try {
value = entry.getParam().get(
entry.getObject());
}
catch (Exception e) {
LOGGER.warn(
"Unable to set value",
e);
continue;
}
if (value == null) {
continue;
}
// Dyn parameter, serialize map.
if (entry.getParam().isDynamicParameter()) {
@SuppressWarnings("unchecked")
Map<String, String> props = (Map<String, String>) value;
for (Map.Entry<String, String> prop : props.entrySet()) {
if (prop.getValue() != null) {
toProperties.put(
String.format(
"%s.%s",
propertyName,
prop.getKey()),
prop.getValue());
}
}
}
else {
toProperties.put(
propertyName,
value.toString());
}
}
}
/**
* Take the given properties list, and convert it to the given objects.
*
* @param fromProperties
*/
public void transformFromProperties(
Properties fromProperties ) {
// This JCommander object is used strictly to use the 'convertValue'
// function which happens to be public.
JCommander jc = new JCommander();
// Translate all fields.
for (TranslationEntry entry : generateEntries()) {
// Get the Properties name.
String propertyName = entry.getAsPropertyName();
propertyName = String.format(
propertyFormat,
propertyName);
// Set the value.
if (entry.getParam().isDynamicParameter()) {
Map<String, String> fromMap = new HashMap<String, String>();
Set<String> propNames = fromProperties.stringPropertyNames();
for (String propName : propNames) {
if (propName.startsWith(propertyName)) {
// Parse
String parsedName = propName.substring(propertyName.length() + 1);
fromMap.put(
parsedName,
fromProperties.getProperty(propName));
}
}
// Set the map.
entry.getParam().set(
entry.getObject(),
fromMap);
}
else {
String value = fromProperties.getProperty(propertyName);
if (value != null) {
// Convert the value to the expected format, and
// set it on the original object.
entry.getParam().set(
entry.getObject(),
jc.convertValue(
entry.getParam(),
entry.getParam().getType(),
value));
}
}
}
}
}