package mil.nga.giat.geowave.adapter.vector.utils;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.JsonParseException;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.SerializationConfig;
import org.opengis.feature.simple.SimpleFeatureType;
/**
*
* Represents a set of configurations maintained within the user data of a
* simple feature type and is tracked by the type name.
*
*/
public class SimpleFeatureUserDataConfigurationSet
{
private static Logger LOGGER = LoggerFactory.getLogger(SimpleFeatureUserDataConfigurationSet.class);
public static final String SIMPLE_FEATURE_CONFIG_FILE_PROP = "SIMPLE_FEATURE_CONFIG_FILE";
/**
* Name string accessed Map of SimpleFeatureUserDataConfiguration in this
* object. The name is the SimpleFeatureType name that will have a
* configuration set.
*/
private Map<String, List<SimpleFeatureUserDataConfiguration>> configurations = new HashMap<String, List<SimpleFeatureUserDataConfiguration>>();
/**
* Default Constructor<br>
*
*/
public SimpleFeatureUserDataConfigurationSet() {}
/**
* Constructor<br>
* Creates a new SimpleFeatureUserDataConfigurationSet configured using the
* passed in SimpleFeature type. Will be accessed using the type name.
*
* @param type
* - SFT to be configured
*/
public SimpleFeatureUserDataConfigurationSet(
final SimpleFeatureType type ) {
List<SimpleFeatureUserDataConfiguration> sfudc = getConfigurationsForType(type.getTypeName());
for (final SimpleFeatureUserDataConfiguration configuration : sfudc) {
configuration.configureFromType(type);
}
}
/**
* Constructor<br>
* Creates a new SimpleFeatureUserDataConfigurationSet configured using the
* passed in SimpleFeature type and adding the passed in configurations.
* Will be accessed using the type name.
*
* @param type
* @param configurations
*/
public SimpleFeatureUserDataConfigurationSet(
final SimpleFeatureType type,
final List<SimpleFeatureUserDataConfiguration> configurations ) {
super();
getConfigurationsForType(
type.getTypeName()).addAll(
configurations);
configureFromType(type);
}
/**
*
* @return a Map of all the SimpleFeatureUserDataConfiguration's by name
*/
public Map<String, List<SimpleFeatureUserDataConfiguration>> getConfigurations() {
return configurations;
}
/**
* Gets a List of all the SimpleFeatureUserDataConfigurations for the SFT
* specified by the 'typeName' string
*
* @param typeName
* - SFT configuration desired
* @return - List<SimpleFeatureUserDataConfigurations>
*/
public synchronized List<SimpleFeatureUserDataConfiguration> getConfigurationsForType(
String typeName ) {
List<SimpleFeatureUserDataConfiguration> configList = configurations.get(typeName);
if (configList == null) {
configList = new ArrayList<SimpleFeatureUserDataConfiguration>();
configurations.put(
typeName,
configList);
}
return configList;
}
/**
* Add the passed in configuration to the list of configurations for the
* specified type name
*
* @param typeName
* - name of type which will get an added configuration
* @param config
* - configuration to be added
*/
public void addConfigurations(
String typeName,
final SimpleFeatureUserDataConfiguration config ) {
getConfigurationsForType(
typeName).add(
config);
}
/**
* Updates the entire list of SimpleFeatureUserDataConfiguration(s) with
* information from the passed in SF type
*
* @param type
* - SF type to be updated
*/
public void configureFromType(
final SimpleFeatureType type ) {
List<SimpleFeatureUserDataConfiguration> sfudc = getConfigurationsForType(type.getTypeName());
// Go through list of SFUD configurations and update each one with
// information from the
// passed in SF type
for (final SimpleFeatureUserDataConfiguration configuration : sfudc) {
configuration.configureFromType(type);
}
}
/**
* Updates the SFT with the entire list of
* SimpleFeatureUserDataConfiguration(s)
*
* @param type
* - SF type to be updated
*/
public void updateType(
final SimpleFeatureType type ) {
List<SimpleFeatureUserDataConfiguration> sfudc = getConfigurationsForType(type.getTypeName());
// Go through list of SFUD configurations and update each one in the
// passed in SF type
for (final SimpleFeatureUserDataConfiguration configuration : sfudc) {
configuration.updateType(type);
}
}
/**
*
* @return JSON formatted string representing the
* SimpleFeatureUserDataConfigurationSet represented by this object
* @throws JsonMappingException
* @throws JsonGenerationException
* @throws IOException
*/
@SuppressWarnings("deprecation")
public String asJsonString()
throws JsonGenerationException,
JsonMappingException,
IOException {
final ObjectMapper mapper = new ObjectMapper();
final SerializationConfig serializationConfig = mapper.getSerializationConfig();
serializationConfig.disable(SerializationConfig.Feature.FAIL_ON_EMPTY_BEANS);
return mapper.writeValueAsString(this);
}
/**
* Converts a JSON formatted config string to a
* SimpleFeatureUserDataConfiguationSet and updates the passed in SFT
*
* @param jsonConfigString
* - json formatted configuration string
* @param type
* - SFT to be updated from the JSON String
*
* @throws JsonMappingException
* @throws JsonParseException
* @throws IOException
*/
@SuppressWarnings("deprecation")
public void fromJsonString(
final String jsonConfigString,
final SimpleFeatureType type )
throws JsonParseException,
JsonMappingException,
IOException {
final ObjectMapper mapper = new ObjectMapper();
final SerializationConfig serializationConfig = mapper.getSerializationConfig();
serializationConfig.disable(SerializationConfig.Feature.FAIL_ON_EMPTY_BEANS);
final SimpleFeatureUserDataConfigurationSet instance = mapper.readValue(
jsonConfigString,
SimpleFeatureUserDataConfigurationSet.class);
configurations = instance.configurations;
updateType(type);
}
/**
* Method that reads user data configuration information from
* {@value #SIMPLE_FEATURE_CONFIG_FILE_PROP} and updates the passed in SFT.
*
* @param type
* - SFT to be updated
*
* @return the SFT passed in as a parameter
*/
@SuppressWarnings("deprecation")
public static SimpleFeatureType configureType(
final SimpleFeatureType type ) {
// HP Fortify "Path Manipulation" false positive
// What Fortify considers "user input" comes only
// from users with OS-level access anyway
final String configFileName = System.getProperty(SIMPLE_FEATURE_CONFIG_FILE_PROP);
if (configFileName != null) {
final File configFile = new File(
configFileName);
if (configFile.exists() && configFile.canRead()) {
try (FileInputStream input = new FileInputStream(
configFile); Reader reader = new InputStreamReader(
input,
"UTF-8")) {
final ObjectMapper mapper = new ObjectMapper();
final SerializationConfig serializationConfig = mapper.getSerializationConfig();
serializationConfig.disable(SerializationConfig.Feature.FAIL_ON_EMPTY_BEANS);
final SimpleFeatureUserDataConfigurationSet instance = mapper.readValue(
reader,
SimpleFeatureUserDataConfigurationSet.class);
instance.updateType(type);
}
catch (final IOException e) {
// HP Fortify "Log Forging" false positive
// What Fortify considers "user input" comes only
// from users with OS-level access anyway
LOGGER.error(
"Cannot parse JSON congiguration file " + configFileName,
e);
}
}
}
return type;
}
}