/* * GeoTools - The Open Source Java GIS Toolkit * http://geotools.org * * (C) 2014, Open Source Geospatial Foundation (OSGeo) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. */ package org.geotools.process.spatialstatistics.operations; import java.io.BufferedReader; import java.io.Closeable; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStreamReader; import java.nio.charset.Charset; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.geotools.util.logging.Logging; import com.vividsolutions.jts.geom.Geometry; import com.vividsolutions.jts.geom.GeometryCollection; import com.vividsolutions.jts.geom.LineString; import com.vividsolutions.jts.geom.MultiLineString; import com.vividsolutions.jts.geom.MultiPoint; import com.vividsolutions.jts.geom.MultiPolygon; import com.vividsolutions.jts.geom.Point; import com.vividsolutions.jts.geom.Polygon; /** * TextColumn * * @author Minpa Lee, MangoSystem * * @source $URL$ */ @SuppressWarnings("nls") public class TextColumn { protected static final Logger LOGGER = Logging.getLogger(TextColumn.class); // Unicode char represented by the UTF-8 byte order mark (EF BB BF) private static final String UTF8_BOM = "\uFEFF"; private static final String prefix = "col_"; public static final Map<String, String> reservedMap = new HashMap<String, String>(); static { reservedMap.put("^", "\\^"); reservedMap.put("$", "\\$"); reservedMap.put("+", "\\+"); reservedMap.put("*", "\\*"); reservedMap.put(".", "\\."); reservedMap.put("|", "\\|"); } private static final String[] attributesTypes = new String[] { "String", "Short", "Integer", "Long", "Float", "Double", "BigDecimal", "Date", "Boolean" }; private static final String[] spatialTypes = new String[] { "String", "Short", "Integer", "Long", "Float", "Double", "BigDecimal", "Date", "Boolean", "X Coordinate", "Y Coordinate", "Point", "MultiPoint", "MultiLineString", "MultiPolygon" }; public static String[] getFieldTypes(boolean isSpatial) { if (isSpatial) { return spatialTypes; } else { return attributesTypes; } } private String name; private String type; private int length = 254; private int columnIndex = -1; private List<String> sampleValues = new ArrayList<String>(); public TextColumn() { } public TextColumn(String name, String type, int length) { setName(name); setType(type); setLength(length); } public String getName() { return name; } public void setName(String name) { this.name = name.trim(); } public String getType() { return type; } public Class<?> getBinding() { if (isX() || isY()) { return Double.class; } else { return findBestBinding(getType()); } } public void setType(String type) { this.type = type; } public boolean isX() { return type.equalsIgnoreCase("X Coordinate"); } public boolean isY() { return type.equalsIgnoreCase("Y Coordinate"); } public boolean isGeometry() { return Geometry.class.isAssignableFrom(getBinding()); } public int getLength() { return length; } public void setLength(int length) { this.length = length; } public int getColumnIndex() { return columnIndex; } public void setColumnIndex(int columnIndex) { this.columnIndex = columnIndex; } public List<String> getSampleValues() { return sampleValues; } public void setSampleValues(List<String> sampleValues) { this.sampleValues = sampleValues; } public String[] getItems() { String[] items = new String[3 + sampleValues.size()]; items[0] = name; items[1] = type; items[2] = String.valueOf(length); for (int index = 0; index < sampleValues.size(); index++) { items[3 + index] = sampleValues.get(index); } return items; } public Class<?> findBestBinding(String typeName) { Class<?> binding = null; if (typeName.contains("AUTOINCREMENT") || typeName.contains("SERIAL") || typeName.contains("COUNTER")) { binding = Integer.class; return binding; } if ("GEOMETRY".equalsIgnoreCase(typeName)) { binding = Geometry.class; } else if ("MULTIPOLYGON".equalsIgnoreCase(typeName)) { binding = MultiPolygon.class; } else if ("MULTILINESTRING".equalsIgnoreCase(typeName)) { binding = MultiLineString.class; } else if ("MULTIPOINT".equalsIgnoreCase(typeName)) { binding = MultiPoint.class; } else if ("POLYGON".equalsIgnoreCase(typeName)) { binding = Polygon.class; } else if ("LINESTRING".equalsIgnoreCase(typeName)) { binding = LineString.class; } else if ("POINT".equalsIgnoreCase(typeName)) { binding = Point.class; } else if ("GEOMETRYCOLLECTION".equalsIgnoreCase(typeName)) { binding = GeometryCollection.class; } else if ("SMALLINT".equalsIgnoreCase(typeName)) { binding = Short.class; } else if ("SHORT".equalsIgnoreCase(typeName)) { binding = Short.class; } else if ("INTEGER".equalsIgnoreCase(typeName)) { binding = Integer.class; } else if ("INT4".equalsIgnoreCase(typeName)) { binding = Integer.class; } else if ("LONG".equalsIgnoreCase(typeName)) { binding = Long.class; } else if ("BIGINT".equalsIgnoreCase(typeName)) { binding = Long.class; } else if ("REAL".equalsIgnoreCase(typeName)) { binding = Float.class; } else if ("FLOAT".equalsIgnoreCase(typeName)) { binding = Double.class; } else if ("FLOAT8".equalsIgnoreCase(typeName)) { binding = Double.class; } else if ("INT8".equalsIgnoreCase(typeName)) { binding = Long.class; } else if ("DOUBLE".equalsIgnoreCase(typeName)) { binding = Double.class; } else if ("DECIMAL".equalsIgnoreCase(typeName)) { binding = Double.class; } else if ("BigDecimal".equalsIgnoreCase(typeName)) { binding = Double.class; } else if ("NUMERIC".equalsIgnoreCase(typeName)) { binding = Double.class; } else if (typeName.contains("CHAR")) { binding = String.class; } else if ("CLOB".equalsIgnoreCase(typeName)) { binding = String.class; } else if ("TEXT".equalsIgnoreCase(typeName)) { binding = String.class; } else if ("STRING".equalsIgnoreCase(typeName)) { binding = String.class; } else if ("DATE".equalsIgnoreCase(typeName)) { binding = Date.class; } else if ("DATETIME".equalsIgnoreCase(typeName)) { binding = Date.class; } else if ("TIMESTAMP".equalsIgnoreCase(typeName)) { binding = Date.class; } else if ("BLOB".equalsIgnoreCase(typeName)) { binding = byte[].class; } else if ("BINARY".equalsIgnoreCase(typeName)) { binding = byte[].class; } else if ("LONGBINARY".equalsIgnoreCase(typeName)) { binding = byte[].class; } else if ("LONGVARBINARY".equalsIgnoreCase(typeName)) { binding = byte[].class; } else if ("VARBINARY".equalsIgnoreCase(typeName)) { binding = byte[].class; } return binding; } public static TextColumn[] getColumns(File textFile, Charset charset, String splitter, boolean headerFirst) { if (reservedMap.containsKey(splitter)) { splitter = reservedMap.get(splitter); } TextColumn[] columns = null; BufferedReader reader = null; try { reader = new BufferedReader(new InputStreamReader(new FileInputStream(textFile), charset)); int sampleSize = 1; String line = reader.readLine(); if (line == null) { return columns; } String[] values = line.split(splitter); // build header boolean isUTF8 = charset.equals(Charset.forName("UTF-8")); columns = new TextColumn[values.length]; for (int index = 0; index < values.length; index++) { columns[index] = new TextColumn(); columns[index].setType("String"); columns[index].setColumnIndex(index); String value = removeDoubleQuote(values[index]).trim(); if (index == 0 && isUTF8 && value.startsWith(UTF8_BOM)) { value = value.substring(1); } if (headerFirst) { columns[index].setName(value); } else { columns[index].setName(prefix + index); columns[index].getSampleValues().add(value); } } // build sample value int limitLength = columns.length - 1; while (line != null) { line = reader.readLine(); sampleSize++; values = line.split(splitter); for (int index = 0; index < values.length; index++) { if (index > limitLength) { break; } columns[index].getSampleValues().add(removeDoubleQuote(values[index])); } if (sampleSize >= 5) { break; } } } catch (FileNotFoundException e) { LOGGER.log(Level.FINER, e.getMessage(), e); } catch (IOException e) { LOGGER.log(Level.FINER, e.getMessage(), e); } finally { closeQuietly(reader); } return columns; } private static final Pattern pattern = Pattern.compile("^\"|\"$"); public static String removeDoubleQuote(String value) { Matcher matcher = pattern.matcher(value); if (matcher.find()) { return matcher.replaceAll("").trim(); } else { return value.trim(); } } private static void closeQuietly(Closeable io) { try { if (io != null) { io.close(); } } catch (IOException e) { LOGGER.log(Level.FINER, e.getMessage(), e); } } }