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 @ 44455

History | View | Annotate | Download (7.81 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

    
20
        public List<String> nextRowValues();
21
    }
22

    
23
    private static class PossibleDataType {
24

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

    
34
    private final String filename;
35

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

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

    
44
    private String getFullFileName() {
45
        return this.filename;
46
    }
47

    
48
    @SuppressWarnings({"UseSpecificCatch", "ResultOfObjectAllocationIgnored"})
49
    public int[] detect(int columns, Rows rows, boolean isFirstLineHeader, Locale locale) throws IOException {
50
        List<PossibleDataType> possibleDataTypes;
51
        int[] types = null;
52

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

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

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

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

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

    
215
}