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.csv / src / main / java / org / gvsig / fmap / dal / store / csv / AutomaticDetectionOfTypes.java @ 43983

History | View | Annotate | Download (7.83 KB)

1
package org.gvsig.fmap.dal.store.csv;
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 org.gvsig.fmap.dal.DataTypes;
9
import org.gvsig.tools.ToolsLocator;
10
import org.gvsig.tools.dataTypes.DataTypesManager;
11

    
12
/**
13
 *
14
 * @author jjdelcerro
15
 */
16
public class AutomaticDetectionOfTypes {
17

    
18
    public interface Rows {
19
        public List<String> nextRowValues();
20
    }
21
    
22
    private static class PossibleDataType {
23

    
24
        public boolean possibleInt = true;
25
        public boolean possibleFloat = true;
26
        public boolean possibleDouble = true;
27
        public boolean possibleLong = true;
28
        public boolean possibleURL = true;
29
        public boolean possibleDate = true;
30
        public boolean possibleGeometry = true;
31
    }
32

    
33
    private final String filename;
34

    
35
    public AutomaticDetectionOfTypes() {
36
        this("(unknown)");
37
    }
38

    
39
    public AutomaticDetectionOfTypes(String filename) {
40
        this.filename = filename;
41
    }
42

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

    
52
        int lineno = 0;
53
        try {
54
            if (isFirstLineHeader) {
55
                rows.nextRowValues();
56
                lineno++;
57
            }
58
            possibleDataTypes = new ArrayList<>(columns);
59
            for (int i = 0; i < columns; i++) {
60
                possibleDataTypes.add(new PossibleDataType());
61
            }
62
            if (locale == null) {
63
                locale = Locale.getDefault();
64
            }
65
            DataTypesManager typeManager = ToolsLocator.getDataTypesManager();
66
            DataTypesManager.CoercionWithLocale toDouble = (DataTypesManager.CoercionWithLocale) typeManager.getCoercion(DataTypes.DOUBLE);
67
            DataTypesManager.CoercionWithLocale toFloat = (DataTypesManager.CoercionWithLocale) typeManager.getCoercion(DataTypes.FLOAT);
68
            DataTypesManager.CoercionWithLocale toDate = (DataTypesManager.CoercionWithLocale) typeManager.getCoercion(DataTypes.DATE);
69
            DataTypesManager.CoercionWithLocale toInt = (DataTypesManager.CoercionWithLocale) typeManager.getCoercion(DataTypes.INT);
70
            DataTypesManager.CoercionWithLocale toLong = (DataTypesManager.CoercionWithLocale) typeManager.getCoercion(DataTypes.LONG);
71
            DataTypesManager.Coercion toGeom = typeManager.getCoercion(DataTypes.GEOMETRY);
72

    
73
            List<String> row = rows.nextRowValues();
74
            lineno++;
75

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

    
172
    @SuppressWarnings("UseSpecificCatch")
173
    private boolean isValidLong(String s) {
174
        if (s == null) {
175
            return true;
176
        }
177
        s = s.trim().toLowerCase();
178
        if (s.isEmpty()) {
179
            return true;
180
        }
181
        try {
182
            if (s.startsWith("0x")) {
183
                Long.valueOf(s.substring(2), 16);
184
            } else {
185
                Long.valueOf(s);
186
            }
187
            return true;
188
        } catch (Exception ex) {
189
            return false;
190
        }
191
    }
192

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