package mil.nga.giat.geowave.cli.osm.osmfeature; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.fasterxml.jackson.core.JsonFactory; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import mil.nga.giat.geowave.cli.osm.osmfeature.types.attributes.AttributeDefinition; import mil.nga.giat.geowave.cli.osm.osmfeature.types.features.FeatureDefinition; import mil.nga.giat.geowave.cli.osm.osmfeature.types.features.FeatureDefinitionSet; import mil.nga.giat.geowave.cli.osm.osmfeature.types.features.FeatureType; public class FeatureConfigParser { private final static Logger LOGGER = LoggerFactory.getLogger(FeatureConfigParser.class); private final JsonFactory factory = new JsonFactory(); public void parseConfig( InputStream configStream ) throws IOException { ObjectMapper om = new ObjectMapper(); JsonNode rootNode = om.readTree(configStream); JsonNode tables = rootNode.path("tables"); Iterator<Map.Entry<String, JsonNode>> nodeIterator = tables.fields(); while (nodeIterator.hasNext()) { Map.Entry<String, JsonNode> feature = nodeIterator.next(); FeatureDefinition fd = parseFeature( feature.getKey(), feature.getValue()); FeatureDefinitionSet.Features.add(fd); } } private static FeatureDefinition parseFeature( String name, JsonNode node ) { FeatureDefinition fd = new FeatureDefinition(); fd.name = name; Iterator<Map.Entry<String, JsonNode>> featureIterator = node.fields(); while (featureIterator.hasNext()) { Map.Entry<String, JsonNode> props = featureIterator.next(); switch (props.getKey()) { case "fields": { parseFields( props.getValue(), fd); break; } case "type": { switch (props.getValue().asText()) { case "polygon": { fd.type = FeatureType.Polygon; break; } case "linestring": { fd.type = FeatureType.LineString; break; } case "point": { fd.type = FeatureType.Point; break; } case "geometry": { fd.type = FeatureType.Geometry; break; } case "validated_geometry": { fd.type = FeatureType.Geometry; break; } default: break; } break; } case "mapping": { parseMapping( props.getValue(), fd); break; } case "mappings": { parseSubMappings( props.getValue(), fd); break; } case "filters": { parseFilters( props.getValue(), fd); break; } default: break; } } return fd; } private static void parseFilters( JsonNode node, FeatureDefinition fd ) { Iterator<Map.Entry<String, JsonNode>> filterIter = node.fields(); while (filterIter.hasNext()) { Map.Entry<String, JsonNode> filterKVP = filterIter.next(); Map<String, List<String>> filter = new HashMap<>(); List<String> filterVals = new ArrayList<>(); for (JsonNode filterVal : filterKVP.getValue()) { filterVals.add(filterVal.asText()); } filter.put( filterKVP.getKey(), filterVals); fd.filters.add(filter); } } private static void parseMapping( JsonNode node, FeatureDefinition fd ) { Iterator<Map.Entry<String, JsonNode>> mappingIter = node.fields(); while (mappingIter.hasNext()) { Map.Entry<String, JsonNode> mapKVP = mappingIter.next(); final List<String> mapValues = new ArrayList<>(); for (JsonNode mapVal : mapKVP.getValue()) { mapValues.add(mapVal.asText()); } fd.mappings.put( mapKVP.getKey(), mapValues); fd.mappingKeys.add(mapKVP.getKey()); } } private static void parseSubMappings( JsonNode node, FeatureDefinition fd ) { Iterator<Map.Entry<String, JsonNode>> mappingsIter = node.fields(); while (mappingsIter.hasNext()) { Map.Entry<String, JsonNode> mappingsKVP = mappingsIter.next(); for (JsonNode mapping : mappingsKVP.getValue()) { Iterator<Map.Entry<String, JsonNode>> mappIter = mapping.fields(); while (mappIter.hasNext()) { Map.Entry<String, JsonNode> mappKVP = mappIter.next(); final Map<String, List<String>> submapping = new HashMap<>(); final List<String> submappingValues = new ArrayList<>(); for (JsonNode subMapVal : mappKVP.getValue()) { submappingValues.add(subMapVal.asText()); } submapping.put( mappKVP.getKey(), submappingValues); if (!fd.subMappings.containsKey(mappingsKVP.getKey())) { fd.subMappings.put( mappingsKVP.getKey(), new ArrayList<Map<String, List<String>>>()); } fd.subMappings.get( mappingsKVP.getKey()).add( submapping); fd.mappingKeys.add(mappKVP.getKey()); } } } } private static void parseFields( JsonNode node, FeatureDefinition fd ) { for (JsonNode attr : node) { Iterator<Map.Entry<String, JsonNode>> fieldIterator = attr.fields(); final AttributeDefinition ad = new AttributeDefinition(); while (fieldIterator.hasNext()) { Map.Entry<String, JsonNode> field = fieldIterator.next(); switch (field.getKey()) { case "type": { ad.type = field.getValue().asText(); break; } case "name": { ad.name = field.getValue().asText(); break; } case "key": { ad.key = field.getValue().asText(); break; } case "args": { Iterator<Map.Entry<String, JsonNode>> argsIterator = field.getValue().fields(); while (argsIterator.hasNext()) { Map.Entry<String, JsonNode> arg = argsIterator.next(); List<String> allArgs = new ArrayList<>(); for (JsonNode item : arg.getValue()) { allArgs.add(item.asText()); } ad.args.put( arg.getKey(), allArgs); } break; } } } fd.attributes.add(ad); } } }