Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.compat.cdc / org.gvsig.fmap.dal / org.gvsig.fmap.dal.file / org.gvsig.fmap.dal.file.lib / src / main / java / org / gvsig / fmap / dal / feature / spi / simpleprovider / AutomaticDetectionOfTypes.java @ 44669

History | View | Annotate | Download (8.45 KB)

1
package org.gvsig.fmap.dal.feature.spi.simpleprovider;
2

    
3
import java.io.IOException;
4
import java.net.URL;
5
import java.util.ArrayList;
6
import java.util.List;
7
import java.util.Locale;
8
import java.util.Objects;
9
import org.gvsig.fmap.dal.DataTypes;
10
import org.gvsig.tools.ToolsLocator;
11
import org.gvsig.tools.dataTypes.Coercion;
12
import org.gvsig.tools.dataTypes.CoercionContext;
13
import org.gvsig.tools.dataTypes.DataTypeUtils;
14
import org.gvsig.tools.dataTypes.DataTypesManager;
15

    
16
/**
17
 *
18
 * @author jjdelcerro
19
 */
20
public class AutomaticDetectionOfTypes {
21

    
22
    public interface Rows {
23
        public List<Object> read();
24
    }
25
    
26
    private static class PossibleDataType {
27

    
28
        public boolean possibleInt = true;
29
        public boolean possibleFloat = true;
30
        public boolean possibleDouble = true;
31
        public boolean possibleDecimal = true;
32
        public boolean possibleLong = true;
33
        public boolean possibleURL = true;
34
        public boolean possibleDate = true;
35
        public boolean possibleGeometry = true;
36
    }
37

    
38
    private final String filename;
39

    
40
    public AutomaticDetectionOfTypes() {
41
        this("(unknown)");
42
    }
43

    
44
    public AutomaticDetectionOfTypes(String filename) {
45
        this.filename = filename;
46
    }
47

    
48
    private String getFullFileName() {
49
        return this.filename;
50
    }
51
    
52
    @SuppressWarnings({"UseSpecificCatch", "ResultOfObjectAllocationIgnored"})
53
    public int[] detect(int columns, Rows rows, boolean isFirstLineHeader, Locale locale) throws IOException {
54
        List<PossibleDataType> possibleDataTypes;
55
        int[] types = null;
56

    
57
        int lineno = 0;
58
        try {
59
            if (isFirstLineHeader) {
60
                rows.read();
61
                lineno++;
62
            }
63
            possibleDataTypes = new ArrayList<>(columns);
64
            for (int i = 0; i < columns; i++) {
65
                possibleDataTypes.add(new PossibleDataType());
66
            }
67
            if (locale == null) {
68
                locale = Locale.getDefault();
69
            }
70
            DataTypesManager typeManager = ToolsLocator.getDataTypesManager();
71
            Coercion toDecimal = typeManager.getCoercion(DataTypes.DECIMAL);
72
            Coercion toDouble = typeManager.getCoercion(DataTypes.DOUBLE);
73
            Coercion toFloat = typeManager.getCoercion(DataTypes.FLOAT);
74
            Coercion toDate = typeManager.getCoercion(DataTypes.DATE);
75
            Coercion toInt = typeManager.getCoercion(DataTypes.INT);
76
            Coercion toLong = typeManager.getCoercion(DataTypes.LONG);
77
            Coercion toGeom = typeManager.getCoercion(DataTypes.GEOMETRY);
78
            CoercionContext coercionContext = DataTypeUtils.coerceContextLocale(locale);
79
            
80
            List<Object> row = rows.read();
81
            lineno++;
82

    
83
            while (row != null) {
84
                for (int i = 0; i < row.size(); i++) {
85
                    while( possibleDataTypes.size()<row.size() ) {
86
                        possibleDataTypes.add(new PossibleDataType());
87
                    }
88
                    String rawvalue = Objects.toString(row.get(i),null);
89
                    PossibleDataType possibleDataType = possibleDataTypes.get(i);
90
                    if (possibleDataType.possibleDecimal) {
91
                        try {
92
                            toDecimal.coerce(rawvalue, coercionContext);
93
                            possibleDataType.possibleDecimal = true;
94
                        } catch (Exception ex) {
95
                            possibleDataType.possibleDecimal = false;
96
                        }
97
                    }
98
                    if (possibleDataType.possibleDouble) {
99
                        try {
100
                            toDouble.coerce(rawvalue, coercionContext);
101
                            possibleDataType.possibleDouble = true;
102
                        } catch (Exception ex) {
103
                            possibleDataType.possibleDouble = false;
104
                        }
105
                    }
106
                    if (possibleDataType.possibleFloat) {
107
                        try {
108
                            toFloat.coerce(rawvalue, coercionContext);
109
                            possibleDataType.possibleFloat = true;
110
                        } catch (Exception ex) {
111
                            possibleDataType.possibleFloat = false;
112
                        }
113
                    }
114
                    if (possibleDataType.possibleLong) {
115
                        possibleDataType.possibleLong = isValidLong(rawvalue);
116
                    }
117
                    if (possibleDataType.possibleInt) {
118
                        possibleDataType.possibleInt = isValidInteger(rawvalue);
119
                    }
120
                    if (possibleDataType.possibleDate) {
121
                        try {
122
                            toDate.coerce(rawvalue, coercionContext);
123
                            possibleDataType.possibleDate = true;
124
                        } catch (Exception ex) {
125
                            possibleDataType.possibleDate = false;
126
                        }
127
                    }
128
                    if (possibleDataType.possibleURL) {
129
                        try {
130
                            new URL((String) rawvalue);
131
                            possibleDataType.possibleURL = true;
132
                        } catch (Exception ex) {
133
                            possibleDataType.possibleURL = false;
134
                        }
135
                    }
136
                    if (possibleDataType.possibleGeometry) {
137
                        try {
138
                            toGeom.coerce((String) rawvalue);
139
                            possibleDataType.possibleGeometry = true;
140
                        } catch (Exception ex) {
141
                            possibleDataType.possibleGeometry = false;
142
                        }
143
                    }
144
                }
145
                row = rows.read();
146
            }
147
            int n = 0;
148
            types = new int[possibleDataTypes.size()];
149
            for (PossibleDataType possibleDataType : possibleDataTypes) {
150
                if (possibleDataType.possibleInt) {
151
                    types[n++] = DataTypes.INT;
152
                    continue;
153
                }
154
                if (possibleDataType.possibleLong) {
155
                    types[n++] = DataTypes.LONG;
156
                    continue;
157
                }
158
                if (possibleDataType.possibleDecimal) {
159
                    types[n++] = DataTypes.DECIMAL;
160
                    continue;
161
                }
162
                if (possibleDataType.possibleFloat) {
163
                    // Forzamos los float a double para evitar perder precision
164
                    types[n++] = DataTypes.DOUBLE;
165
                    continue;
166
                }
167
                if (possibleDataType.possibleDouble) {
168
                    types[n++] = DataTypes.DOUBLE;
169
                    continue;
170
                }
171
                if (possibleDataType.possibleURL) {
172
                    types[n++] = DataTypes.URL;
173
                    continue;
174
                }
175
                if (possibleDataType.possibleDate) {
176
                    types[n++] = DataTypes.DATE;
177
                    continue;
178
                }
179
                if (possibleDataType.possibleGeometry) {
180
                    types[n++] = DataTypes.GEOMETRY;
181
                    continue;
182
                }
183
                types[n++] = DataTypes.STRING;
184
            }
185
        } catch (Exception ex) {
186
            throw new RuntimeException("Problems reading file '" + this.getFullFileName() + "' near line " + lineno + ".", ex);
187
        }
188
        return types;
189
    }
190

    
191
    @SuppressWarnings("UseSpecificCatch")
192
    private boolean isValidLong(String s) {
193
        if (s == null) {
194
            return true;
195
        }
196
        s = s.trim().toLowerCase();
197
        if (s.isEmpty()) {
198
            return true;
199
        }
200
        try {
201
            if (s.startsWith("0x")) {
202
                Long.valueOf(s.substring(2), 16);
203
            } else {
204
                Long.valueOf(s);
205
            }
206
            return true;
207
        } catch (Exception ex) {
208
            return false;
209
        }
210
    }
211

    
212
    @SuppressWarnings("UseSpecificCatch")
213
    private boolean isValidInteger(String s) {
214
        if (s == null) {
215
            return true;
216
        }
217
        s = s.trim().toLowerCase();
218
        if (s.isEmpty()) {
219
            return true;
220
        }
221
        try {
222
            if (s.startsWith("0x")) {
223
                Integer.valueOf(s.substring(2), 16);
224
            } else {
225
                Integer.valueOf(s);
226
            }
227
            return true;
228
        } catch (Exception ex) {
229
            return false;
230
        }
231
    }
232
    
233
}