Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.compat.cdc / org.gvsig.fmap.dal / org.gvsig.fmap.dal.db / org.gvsig.fmap.dal.db.jdbc / src / main / java / org / gvsig / fmap / dal / store / jdbc2 / spi / JDBCSQLBuilderBase.java @ 44198

History | View | Annotate | Download (11.8 KB)

1
package org.gvsig.fmap.dal.store.jdbc2.spi;
2

    
3
import java.sql.Connection;
4
import java.sql.PreparedStatement;
5
import java.sql.SQLException;
6
import java.util.ArrayList;
7
import java.util.List;
8
import org.cresques.cts.IProjection;
9
import org.gvsig.expressionevaluator.ExpressionBuilder.GeometrySupportType;
10
import org.gvsig.expressionevaluator.ExpressionBuilder.Parameter;
11
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
12
import org.gvsig.fmap.dal.feature.FeatureReference;
13
import org.gvsig.fmap.dal.feature.FeatureStore;
14
import org.gvsig.fmap.dal.feature.FeatureType;
15
import org.gvsig.fmap.dal.feature.spi.SQLBuilderBase;
16
import org.gvsig.fmap.dal.feature.spi.FeatureProvider;
17
import org.gvsig.fmap.dal.feature.spi.FeatureReferenceProviderServices;
18
import org.gvsig.fmap.dal.store.jdbc2.JDBCHelper;
19
import org.gvsig.fmap.geom.DataTypes;
20
import org.gvsig.fmap.geom.Geometry;
21
import org.gvsig.fmap.geom.GeometryLocator;
22
import org.gvsig.fmap.geom.GeometryManager;
23
import org.gvsig.fmap.geom.aggregate.MultiLine;
24
import org.gvsig.fmap.geom.aggregate.MultiPoint;
25
import org.gvsig.fmap.geom.aggregate.MultiPolygon;
26
import org.gvsig.fmap.geom.exception.CreateGeometryException;
27
import org.gvsig.fmap.geom.primitive.Primitive;
28
import org.gvsig.fmap.geom.type.GeometryType;
29
import org.gvsig.tools.dispose.Disposable;
30

    
31
@SuppressWarnings("UseSpecificCatch")
32
public class JDBCSQLBuilderBase extends SQLBuilderBase {
33

    
34
    public static final String PROP_FEATURE_TYPE = "FeatureType";
35
    public static final String PROP_TABLE = "Table";
36
    
37
    private GeometryManager geometryManager = null;
38
    protected final JDBCHelper helper;
39
    
40
    public JDBCSQLBuilderBase(JDBCHelper helper) {
41
        super();
42
        this.helper = helper;
43
    }
44
    
45
    public JDBCHelper getHelper() {
46
        return helper;
47
    }
48
    
49
    protected GeometryManager getGeometryManager() {
50
        if (this.geometryManager == null) {
51
            this.geometryManager = GeometryLocator.getGeometryManager();
52
        }
53
        return this.geometryManager;
54
    }
55
    
56
    @Override
57
    public Object srs_id(IProjection projection) {
58
        Connection conn = null;
59
        try {
60
            conn = this.helper.getConnection();
61
            SRSSolver solver = this.helper.getSRSSolver();
62
            Object srscode = solver.getDatabaseCode(conn, projection);
63
//            logger.debug("database code srs {}, type {}, srssolver {}.", 
64
//                new Object[] { 
65
//                    srscode, 
66
//                    srscode==null? "null":srscode.getClass().getSimpleName(), 
67
//                    solver
68
//                }
69
//            );
70
            return srscode;
71
        } catch (Exception ex) {
72
            throw new RuntimeException("Can't locate database code for SRS '"+projection.getAbrev()+"'.");
73
        } finally {
74
            this.helper.closeConnectionQuietly(conn);
75
        }
76
    }
77
    
78
    public void setParameters(PreparedStatement st) {
79
        try {
80
            int columnIndex = 1;
81
            for (Parameter parameter : this.parameters()) {
82
                st.setObject(columnIndex++, parameter.value());
83
            }
84
        } catch (Exception ex) {
85
            String p = "unknow";
86
            try {
87
                p =  this.parameters().toString();
88
            } catch (Exception ex2) {
89
                // Do nothing
90
            }
91
            throw new RuntimeException("Can't set parameters to prepared statement from parameters (" + p + ")", ex);
92
        }
93
    }
94

    
95
    public Disposable setParameters(PreparedStatement st, FeatureProvider feature) {
96
        try {
97
            FeatureType type = feature.getType();
98
            List<Object> values = new ArrayList<>();
99
            Object value;
100
            for (Parameter parameter : this.parameters()) {
101
                if (parameter.is_constant()) {
102
                    value = parameter.value();
103
                    values.add(value);
104
                } else {
105
                    String name = parameter.name();
106
                    value = feature.get(name);
107
                    FeatureAttributeDescriptor attrDesc = type.getAttributeDescriptor(name);
108
                    if( attrDesc.getType()==DataTypes.GEOMETRY ) {
109
                        value = forceGeometryType(attrDesc.getGeomType(), (Geometry) value);                        
110
                    }
111
                    values.add(value);
112
                }
113
            }
114
            return this.setStatementParameters(st, values, this.geometry_support_type());
115
        } catch (Exception ex) {
116
            String f = "unknow";
117
            try {
118
                f = feature.toString();
119
            } catch (Exception ex2) {
120
                // Do nothing
121
            }
122
            throw new RuntimeException("Can't set parameters to prepared statement from the feature (" + f + ")", ex);
123
        }
124
    }
125
    
126
    protected Geometry forceGeometryType(GeometryType geomtype, Geometry geom) throws CreateGeometryException {
127
        if( geom == null ) {
128
            return null;
129
        }
130
        switch( geomtype.getType() ) {
131
        case Geometry.TYPES.MULTIPOLYGON:
132
            if( geom.getType()==Geometry.TYPES.POLYGON ) {
133
                MultiPolygon x = getGeometryManager().createMultiPolygon(geomtype.getSubType());
134
                x.addPrimitive((Primitive) geom);
135
                geom = x;
136
            }
137
            break;
138
        case Geometry.TYPES.MULTILINE:
139
            if( geom.getType()==Geometry.TYPES.LINE ) {
140
                MultiLine x = getGeometryManager().createMultiLine(geomtype.getSubType());
141
                x.addPrimitive((Primitive) geom);
142
                geom = x;
143
            }
144
            break;
145
        case Geometry.TYPES.MULTIPOINT:
146
            if( geom.getType()==Geometry.TYPES.POINT ) {
147
                MultiLine x = getGeometryManager().createMultiLine(geomtype.getSubType());
148
                x.addPrimitive((Primitive) geom);
149
                geom = x;
150
            }
151
            break;
152
        case Geometry.TYPES.POLYGON:
153
            if( geom.getType()==Geometry.TYPES.MULTIPOLYGON ) {
154
                MultiPolygon x = (MultiPolygon) geom;
155
                if( x.getPrimitivesNumber()==1 ) {
156
                    geom = x.getPrimitiveAt(0);
157
                }
158
            }
159
            break;
160
        case Geometry.TYPES.LINE:
161
            if( geom.getType()==Geometry.TYPES.MULTILINE ) {
162
                MultiLine x = (MultiLine) geom;
163
                if( x.getPrimitivesNumber()==1 ) {
164
                    geom = x.getPrimitiveAt(0);
165
                }
166
            }
167
            break;
168
        case Geometry.TYPES.POINT:
169
            if( geom.getType()==Geometry.TYPES.MULTIPOINT ) {
170
                MultiPoint x = (MultiPoint) geom;
171
                if( x.getPrimitivesNumber()==1 ) {
172
                    geom = x.getPrimitiveAt(0);
173
                }
174
            }
175
        }
176
        return geom;
177
    }
178
    
179
    public Disposable setParameters(PreparedStatement st, FeatureReference reference) {
180
        try {
181
            
182
            List<Object> values = new ArrayList<>();
183
            for (Parameter parameter : this.parameters()) {
184
                if (parameter.is_constant()) {
185
                    values.add(parameter.value());
186
                } else {
187
                    String name = parameter.name();
188
                    values.add(((FeatureReferenceProviderServices)reference).getKeyValue(name));
189
                }
190
            }
191
            return this.setStatementParameters(st, values, this.geometry_support_type());
192
        } catch (Exception ex) {
193
            String f = "unknow";
194
            try {
195
                f = reference.toString();
196
            } catch (Exception ex2) {
197
                // Do nothing
198
            }
199
            throw new RuntimeException("Can't set parameters to prepared statement from the feature (" + f + ")", ex);
200
        }
201
    }
202

    
203
    public Disposable setStatementParameters(
204
        PreparedStatement st, 
205
        List values, 
206
        GeometrySupportType geometrySupportType) throws SQLException {
207
        
208
        if (values == null) {
209
            return new Disposable() {
210
                @Override
211
                public void dispose() {
212
                }
213
            };
214
        }
215
        if( LOGGER.isDebugEnabled() ) {
216
            StringBuilder debug = new StringBuilder();
217
            debug.append("st.set(");
218
            try {
219
                byte[] bytes;
220
                int columnIndex = 1;
221
                for (Object value : values) {
222
                    if (value instanceof Geometry) {
223
                        switch(geometrySupportType) {
224
                            case WKT:
225
                                value = ((Geometry) value).convertToWKT();
226
                                debug.append("/*");
227
                                debug.append(columnIndex);
228
                                debug.append("*/ ");
229
                                debug.append(as_string(value));
230
                                debug.append(", ");
231
                                break;
232
                            case NATIVE:
233
                            case WKB: 
234
                                bytes = ((Geometry) value).convertToWKB();
235
                                debug.append("/*");
236
                                debug.append(columnIndex);
237
                                debug.append("*/ ");
238
                                debug.append(as_string(bytes));
239
                                debug.append(", ");
240
                                break;
241
                            case EWKB:
242
                                bytes = ((Geometry) value).convertToEWKB();
243
                                debug.append("/*");
244
                                debug.append(columnIndex);
245
                                debug.append("*/ ");
246
                                debug.append(as_string(bytes));
247
                                debug.append(", ");
248
                                break;
249
                        }
250
                    } else {
251
                        debug.append("/*");
252
                        debug.append(columnIndex);
253
                        debug.append("*/ ");
254
                        if( value instanceof String ) {
255
                            debug.append(as_string(value));
256
                        } else if( value instanceof Boolean ) {
257
                            debug.append( ((Boolean)value)? constant_true:constant_false );
258
                        } else {
259
                            debug.append(value);
260
                        }
261
                        debug.append(", ");
262
                    }
263
                    columnIndex++;
264
                }
265
                debug.append(")");
266
                LOGGER.debug(debug.toString());
267
            } catch(Exception ex) {
268
            }        
269
        }
270
        try {
271
            byte[] bytes;
272
            int columnIndex = 1;
273
            for (Object value : values) {
274
                if (value instanceof Geometry) {
275
                    switch(geometrySupportType) {
276
                        case WKT:
277
                            value = ((Geometry) value).convertToWKT();
278
                            st.setObject(columnIndex, value);
279
                            break;
280
                        case NATIVE:
281
                        case WKB: 
282
                            bytes = ((Geometry) value).convertToWKB();
283
                            st.setBytes(columnIndex, bytes);
284
                            break;
285
                        case EWKB:
286
                            bytes = ((Geometry) value).convertToEWKB();
287
                            st.setBytes(columnIndex, bytes);
288
                            break;
289
                    }
290
                } else {
291
                    st.setObject(columnIndex, value);
292
                }
293
                columnIndex++;
294
            }
295
            return new Disposable() {
296
                @Override
297
                public void dispose() {
298
                }
299
            };
300
        } catch(Exception ex) {
301
            throw new SQLException("Can't set values for the prepared statement.", ex);
302
        }        
303
    }
304
}