package mil.nga.giat.geowave.format.geotools.vector.retyping.date; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; import mil.nga.giat.geowave.format.geotools.vector.AbstractFieldRetypingSource; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.geotools.feature.simple.SimpleFeatureTypeBuilder; import org.opengis.feature.simple.SimpleFeature; import org.opengis.feature.simple.SimpleFeatureType; import org.opengis.feature.type.AttributeDescriptor; import org.opengis.feature.type.Name; public class DateFieldRetypingSource extends AbstractFieldRetypingSource { private final static Logger LOGGER = LoggerFactory.getLogger(DateFieldRetypingSource.class); private final SimpleFeatureType typeIn; private final Map<String, String> fieldNameToTimestampFormat; private final ThreadLocal<Map<String, SimpleDateFormat>> fieldToFormatObjMap; public DateFieldRetypingSource( final SimpleFeatureType typeIn, final Map<String, String> fieldNameToTimestampFormat ) { this.typeIn = typeIn; this.fieldNameToTimestampFormat = fieldNameToTimestampFormat; this.fieldToFormatObjMap = new ThreadLocal<Map<String, SimpleDateFormat>>() { @Override protected Map<String, SimpleDateFormat> initialValue() { final Map<String, SimpleDateFormat> localFieldToFormat = new HashMap<>(); for (Entry<String, String> entry : fieldNameToTimestampFormat.entrySet()) { localFieldToFormat.put( entry.getKey(), new SimpleDateFormat( entry.getValue())); } return localFieldToFormat; } }; } @Override public Object retypeAttributeValue( Object value, Name attributeName ) { Object outValue = value; final String localName = attributeName.getLocalPart(); final SimpleDateFormat formatForName = fieldToFormatObjMap.get().get( localName); if (value != null && formatForName != null) { try { outValue = formatForName.parse(value.toString()); } catch (ParseException e) { LOGGER.error("Failed to parse: " + localName + ": " + value.toString()); } } return outValue; } @Override public SimpleFeatureType getRetypedSimpleFeatureType() { debugType( "IN", typeIn); SimpleFeatureTypeBuilder typeOutBuilder = new SimpleFeatureTypeBuilder(); // Manually set the basics and replace the date fields typeOutBuilder.setCRS(typeIn.getCoordinateReferenceSystem()); typeOutBuilder.setDescription(typeIn.getDescription()); typeOutBuilder.setName(typeIn.getName()); for (AttributeDescriptor att : typeIn.getAttributeDescriptors()) { if (fieldNameToTimestampFormat.containsKey(att.getLocalName())) { typeOutBuilder.add( att.getLocalName(), Date.class); } else { typeOutBuilder.add(att); } } // TODO - restore this procedure when support for GeoTools 12.x is // dropped // typeOutBuilder.init(typeIn); // for (Entry<String, String> fieldToChange : // fieldNameToTimestampFormat.entrySet()) { // final AttributeTypeBuilder dateFieldBuilder = new // AttributeTypeBuilder(); // dateFieldBuilder.setName(fieldToChange.getKey()); // dateFieldBuilder.setBinding(Date.class); // typeOutBuilder.set( // fieldToChange.getKey(), // dateFieldBuilder); // } final SimpleFeatureType typeOut = typeOutBuilder.buildFeatureType(); debugType( "OUT", typeOut); return typeOut; } @Override public String getFeatureId( SimpleFeature original ) { // We don't need to do much, we're not changing the ID return original.getID(); } private void debugType( final String typeLabel, final SimpleFeatureType type ) { if (LOGGER.isDebugEnabled()) { final StringBuilder logBuilder = new StringBuilder(); logBuilder.append("Type: " + typeLabel); for (AttributeDescriptor propDef : type.getAttributeDescriptors()) { logBuilder.append("\nField: " + propDef.getLocalName() + ", Type: " + propDef.getType().getBinding().getSimpleName()); } LOGGER.debug(logBuilder.toString()); } } }