Statistics
| Revision:

svn-gvsig-desktop / branches / v2_0_0_prep / extensions / org.gvsig.oracle / src / org / gvsig / fmap / dal / store / oracle / OracleStoreProvider.java @ 37896

History | View | Annotate | Download (27.7 KB)

1
/* gvSIG. Geographic Information System of the Valencian Government
2
 *
3
 * Copyright (C) 2007-2008 Infrastructures and Transports Department
4
 * of the Valencian Government (CIT)
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 2
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21
 */
22

    
23
/*
24
 * AUTHORS (In addition to CIT):
25
 * 2009 Prodevelop S.L. main development
26
 */
27

    
28
package org.gvsig.fmap.dal.store.oracle;
29

    
30
import java.security.InvalidParameterException;
31
import java.sql.Connection;
32
import java.sql.PreparedStatement;
33
import java.sql.ResultSet;
34
import java.sql.SQLException;
35
import java.sql.Statement;
36
import java.util.ArrayList;
37
import java.util.HashMap;
38
import java.util.Iterator;
39
import java.util.List;
40
import java.util.Map;
41

    
42
import oracle.sql.STRUCT;
43
import oracle.sql.TIMESTAMP;
44

    
45
import org.slf4j.Logger;
46
import org.slf4j.LoggerFactory;
47

    
48
import org.gvsig.fmap.dal.DALLocator;
49
import org.gvsig.fmap.dal.DataManager;
50
import org.gvsig.fmap.dal.DataServerExplorer;
51
import org.gvsig.fmap.dal.DataStoreParameters;
52
import org.gvsig.fmap.dal.DataTypes;
53
import org.gvsig.fmap.dal.exception.DataException;
54
import org.gvsig.fmap.dal.exception.InitializeException;
55
import org.gvsig.fmap.dal.exception.OpenException;
56
import org.gvsig.fmap.dal.exception.ReadException;
57
import org.gvsig.fmap.dal.exception.ValidateDataParametersException;
58
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
59
import org.gvsig.fmap.dal.feature.FeatureIndexes;
60
import org.gvsig.fmap.dal.feature.FeatureQuery;
61
import org.gvsig.fmap.dal.feature.FeatureType;
62
import org.gvsig.fmap.dal.feature.exception.CreateFeatureException;
63
import org.gvsig.fmap.dal.feature.impl.DefaultFeatureIndexes;
64
import org.gvsig.fmap.dal.feature.impl.DefaultFeatureStore;
65
import org.gvsig.fmap.dal.feature.spi.AbstractFeatureStoreProvider;
66
import org.gvsig.fmap.dal.feature.spi.FeatureProvider;
67
import org.gvsig.fmap.dal.feature.spi.FeatureReferenceProviderServices;
68
import org.gvsig.fmap.dal.feature.spi.FeatureSetProvider;
69
import org.gvsig.fmap.dal.feature.spi.FeatureStoreProviderServices;
70
import org.gvsig.fmap.dal.resource.ResourceAction;
71
import org.gvsig.fmap.dal.resource.exception.ResourceExecuteException;
72
import org.gvsig.fmap.dal.spi.DataStoreProviderServices;
73
import org.gvsig.fmap.dal.store.db.DBHelper;
74
import org.gvsig.fmap.dal.store.jdbc.JDBCHelper;
75
import org.gvsig.fmap.dal.store.jdbc.JDBCStoreParameters;
76
import org.gvsig.fmap.dal.store.jdbc.JDBCStoreProviderWriter;
77
import org.gvsig.fmap.dal.store.jdbc.exception.JDBCException;
78
import org.gvsig.fmap.dal.store.jdbc.exception.JDBCExecutePreparedSQLException;
79
import org.gvsig.fmap.dal.store.jdbc.exception.JDBCPreparingSQLException;
80
import org.gvsig.fmap.dal.store.jdbc.exception.JDBCSQLException;
81
import org.gvsig.fmap.dal.store.jdbc.exception.JDBCUpdateWithoutChangesException;
82
import org.gvsig.fmap.dal.store.oracle.index.OracleFeatureIndex;
83
import org.gvsig.fmap.dal.store.oracle.index.OracleRemoteFeatureIndexProvider;
84
import org.gvsig.fmap.geom.Geometry;
85
import org.gvsig.fmap.geom.Geometry.SUBTYPES;
86
import org.gvsig.fmap.geom.operation.towkb.ToWKB;
87
import org.gvsig.tools.ToolsLocator;
88
import org.gvsig.tools.dataTypes.CoercionException;
89
import org.gvsig.tools.dataTypes.DataTypesManager;
90
import org.gvsig.tools.dataTypes.impl.coercion.CoerceToDateTime;
91
import org.gvsig.tools.dynobject.DynObject;
92
import org.gvsig.tools.exception.BaseException;
93

    
94
/**
95
 * Oracle Provider
96
 * 
97
 * @author vsanjaime
98
 * 
99
 */
100
public class OracleStoreProvider extends JDBCStoreProviderWriter {
101

    
102
        public final static Logger logger = LoggerFactory
103
                        .getLogger(OracleStoreProvider.class);
104

    
105
        public static String NAME = "Oracle";
106
        public static String DESCRIPTION = "Oracle source";
107
        public static final String METADATA_DEFINITION_NAME = NAME;
108
        
109
        private boolean oracleIndexSet = false;
110
        
111
        private Map selectedFields = null;
112
        
113
        /*
114
        protected static void registerDynClass() {
115
                DynObjectManager dynman = ToolsLocator.getDynObjectManager();
116
                DynClass dynClass;
117
                if (DYNCLASS == null) {
118
                        dynClass = dynman.add(DYNCLASS_NAME, DESCRIPTION);
119

120
                        // dynClass.extend(dynman.get(FeatureStore.DYNCLASS_NAME));
121
                        DYNCLASS = dynClass;
122
                }
123
        }
124
        */
125

    
126
        public OracleStoreProvider(OracleStoreParameters params,
127
                        DataStoreProviderServices storeServices) throws InitializeException {
128
                super(params, storeServices,
129
                                DBHelper.newMetadataContainer(METADATA_DEFINITION_NAME));
130
                
131
                String defaultGeometryAttributeName;
132
                try {
133
                        defaultGeometryAttributeName = this.getFeatureStore()
134
                                .getDefaultFeatureType()
135
                                        .getDefaultGeometryAttributeName();
136
                } catch (DataException e) {
137
                        throw new InitializeException(e);
138
                }
139
                
140
                String ora_srid =
141
                        getOraHelper().getOraTableSrid(params, defaultGeometryAttributeName);
142
                this.setDynValue(OracleStoreParameters.ORA_TABLE_SRID_KEY, ora_srid);
143
                String sFields = (String)getParameters().getDynValue("fields");
144
                if (sFields != null){
145
                    selectedFields = new HashMap();
146
                    String[] fields = sFields.split(",");
147
                    for (int i=0 ; i<fields.length ; i++){
148
                        selectedFields.put(fields[i], Boolean.TRUE);
149
                    }
150
                }
151
        }
152
        
153
        /**
154
         * Default Constructor.
155
         *
156
         * @param params
157
         * @param storeServices
158
         * @param metadata
159
         */
160
        protected OracleStoreProvider(DataStoreParameters params,
161
                        DataStoreProviderServices storeServices, DynObject metadata) throws InitializeException {
162
                super((JDBCStoreParameters) params, storeServices, metadata);
163
        }
164

    
165
        /**
166
         * Constructor when cannot create metada in constrution time. <br>
167
         * <br>
168
         * <strong>Note: </strong> Don't use it if not is necesary. Set metada
169
         * <strong>as soon as posible</strong> by
170
         * {@link AbstractFeatureStoreProvider#setMetadata(DynObject)}
171
         * 
172
         * @param params
173
         * @param storeServices
174
         */
175
        protected OracleStoreProvider(DataStoreParameters params,
176
                        DataStoreProviderServices storeServices) throws InitializeException {
177
                this((JDBCStoreParameters) params, storeServices, null);
178
        }
179
        
180
        
181
        
182

    
183
        private OracleStoreParameters getOracleStoreParameters() {
184
                return (OracleStoreParameters) this.getParameters();
185
        }
186

    
187
        protected JDBCHelper createHelper() throws InitializeException {
188
                return new OracleHelper(this, getOracleStoreParameters());
189
        }
190
        
191
        public void open() throws OpenException {
192
                super.open();
193
                
194
                // =============== add remote oracle geometry index to prevent default index
195
                if (!oracleIndexSet) {
196
                        
197
                        DefaultFeatureStore dfs = null;
198
                        if (!(getFeatureStore() instanceof DefaultFeatureStore)) {
199
                                logger.warn("Feature store not DefaultFeatureStore: " + dfs.getClass().getName());
200
                                return;
201
                        }
202
                        dfs = (DefaultFeatureStore) getFeatureStore();
203
                        
204
                        FeatureType ft = null;
205
            try {
206
                ft = dfs.getDefaultFeatureType();
207
            } catch (DataException e) {
208
                throw new OpenException(getFeatureStore().getName(), e);
209
            }                        
210
                        
211
            //It there is not a geometry the index is not created
212
                        if (ft.getDefaultGeometryAttributeName() != null){
213
                            FeatureIndexes findexes = dfs.getIndexes();
214
                            if (findexes instanceof DefaultFeatureIndexes) {
215
                                    DefaultFeatureIndexes dfi = (DefaultFeatureIndexes) findexes;                                   
216
                                    dfi.addIndex(
217
                                                    new OracleFeatureIndex(
218
                                                                    (FeatureStoreProviderServices) getFeatureStore(),
219
                                                                    ft,
220
                                                                    new OracleRemoteFeatureIndexProvider(dfs),
221
                                                                    ft.getDefaultGeometryAttributeName(),
222
                                                                    OracleRemoteFeatureIndexProvider.NAME));
223
                            }
224
                        }
225
                        oracleIndexSet = true;
226
                }
227
                // ===============                 
228
        }
229

    
230

    
231
        protected String fixFilter(String filter) {
232
                // filter was created by a class in oracle plugin, should not need fix
233
                return filter;
234
        }
235

    
236
        public String getName() {
237
                return NAME;
238
        }
239
        
240
        public int getOIDType() {
241
                return DataTypes.LONG;
242
        }
243
        
244
        private static long ora_oid = 100000000;
245
        
246
        public Object createNewOID() {
247
                return new Long(ora_oid++);
248
        }
249

    
250
        public FeatureSetProvider createSet(FeatureQuery query,
251
                        FeatureType featureType) throws DataException {
252

    
253
                return new OracleSetProvider(this, query, featureType);
254
        }
255

    
256
        public DataServerExplorer getExplorer() throws ReadException {
257
                DataManager manager = DALLocator.getDataManager();
258
                OracleServerExplorerParameters exParams;
259
                OracleStoreParameters params = getOracleStoreParameters();
260
                try {
261
                        exParams = (OracleServerExplorerParameters) manager
262
                                        .createServerExplorerParameters(OracleServerExplorer.NAME);
263
                        exParams.setUrl(params.getUrl());
264
                        exParams.setHost(params.getHost());
265
                        exParams.setPort(params.getPort());
266
                        exParams.setDBName(params.getDBName());
267
                        exParams.setUser(params.getUser());
268
                        exParams.setPassword(params.getPassword());
269
                        exParams.setCatalog(params.getCatalog());
270
                        exParams.setSchema(params.getSchema());
271
                        exParams.setJDBCDriverClassName(params.getJDBCDriverClassName());
272
                        exParams.setUseSSL(params.getUseSSL());
273
                        exParams.setOraDriverType(params.getOraDriverType());
274

    
275
                        return manager.openServerExplorer(OracleServerExplorer.NAME, exParams);
276
                } catch (DataException e) {
277
                        throw new ReadException(this.getName(), e);
278
                } catch (ValidateDataParametersException e) {
279
                        throw new ReadException(this.getName(), e);
280
                }
281
        }
282

    
283
        public boolean allowAutomaticValues() {
284
                return true;
285
        }
286

    
287
        public boolean hasGeometrySupport() {
288
                return true;
289
        }
290

    
291
        protected OracleHelper getOraHelper() {
292
                return (OracleHelper) getHelper();
293
        }
294

    
295
        public boolean canWriteGeometry(int geometryType, int geometrySubtype)
296
                        throws DataException {
297
                FeatureType type = getFeatureStore().getDefaultFeatureType();
298
                FeatureAttributeDescriptor geomAttr = type.getAttributeDescriptor(type
299
                                .getDefaultGeometryAttributeName());
300
                if (geomAttr == null) {
301
                        return false;
302
                }
303
                if (geometrySubtype != geomAttr.getGeometrySubType()) {
304
                        return false;
305
                }
306
                switch (geomAttr.getGeometryType()) {
307
                case Geometry.TYPES.GEOMETRY:
308
                        return true;
309

    
310
                case Geometry.TYPES.MULTISURFACE:
311
                        return geometryType == Geometry.TYPES.MULTISURFACE;
312

    
313
                case Geometry.TYPES.MULTIPOINT:
314
                        return geometryType == Geometry.TYPES.MULTIPOINT;
315

    
316
                case Geometry.TYPES.MULTICURVE:
317
                        return geometryType == Geometry.TYPES.MULTICURVE;
318

    
319
                case Geometry.TYPES.MULTISOLID:
320
                        return geometryType == Geometry.TYPES.MULTISOLID;
321

    
322
                case Geometry.TYPES.SURFACE:
323
                        return geometryType == Geometry.TYPES.SURFACE;
324

    
325
                case Geometry.TYPES.POINT:
326
                        return geometryType == Geometry.TYPES.POINT;
327

    
328
                case Geometry.TYPES.CURVE:
329
                        return geometryType == Geometry.TYPES.CURVE;
330

    
331
                case Geometry.TYPES.SOLID:
332
                        return geometryType == Geometry.TYPES.SOLID;
333

    
334
                default:
335
                        return geometryType == geomAttr.getGeometryType();
336
                }
337

    
338
        }
339

    
340
        protected void addToListFeatureValues(FeatureProvider featureProvider,
341
                        FeatureAttributeDescriptor attrOfList,
342
                        FeatureAttributeDescriptor attr, List values) throws DataException {
343

    
344
                
345
                
346
                // geometry
347
                if (attr.getDataType().getType() == DataTypes.GEOMETRY) {
348
                        Geometry geom = (Geometry) featureProvider.get(attr.getIndex());
349
                        
350
                        String ora_srid_str = null;
351
                        boolean is_geo = false;
352
                        boolean has_srid = false;
353
                        
354
                        Object ora_srid = getDynValue("ora_table_srid");
355
                        if (ora_srid != null) {
356
                            if (ora_srid instanceof String) {
357
                                ora_srid_str = (String) ora_srid; 
358
                            } else {
359
                        if (ora_srid instanceof Integer) {
360
                            ora_srid_str = "" + ((Integer) ora_srid).intValue(); 
361
                        }
362
                            }
363
                        }
364
                        
365
                        has_srid = ora_srid_str != null && ora_srid_str.compareToIgnoreCase("0") != 0; 
366
                        is_geo = OracleUtils.getIsGCS(
367
                            ora_srid_str, has_srid);
368
                        
369
                        // OracleUtils.is
370
                        
371
                        STRUCT stru = OracleUtils.buildSTRUCT(
372
                            geom, 0, helper.getConnection(),
373
                            ora_srid_str, has_srid, false, is_geo);
374
                        values.add(stru);
375
                } else {
376
                        super.addToListFeatureValues(featureProvider, attrOfList, attr, values);
377
                }
378
        }
379

    
380
        protected String getSqlStatementAddField(FeatureAttributeDescriptor attr,
381
                        List additionalStatement) throws DataException {
382

    
383
                if (attr.getDataType().getType() == DataTypes.GEOMETRY) {
384
                        OracleStoreParameters params = getOracleStoreParameters();
385
                        additionalStatement.add(((OracleHelper) helper)
386
                                        .getSqlGeometryFieldAdd(attr, params.getTable(), params
387
                                                        .getSchema()));
388
                }
389

    
390
                return super.getSqlStatementAddField(attr, additionalStatement);
391

    
392
        }
393

    
394
        protected String getSqlStatementDropField(FeatureAttributeDescriptor attr,
395
                        List additionalStatement) {
396
                String result = super.getSqlStatementDropField(attr,
397
                                additionalStatement);
398
                if (attr.getDataType().getType() == DataTypes.GEOMETRY) {
399
                        additionalStatement.add(getSqlGeometryFieldDrop(attr));
400
                }
401
                return result;
402
        }
403

    
404
        protected List<String> getSqlStatementAlterField(
405
                        FeatureAttributeDescriptor attrOrg,
406
                        FeatureAttributeDescriptor attrTrg, List additionalStatement)
407
                        throws DataException {
408

    
409
                List<String> actions = new ArrayList<String>();
410
                StringBuilder strb;
411
                OracleStoreParameters params = getOracleStoreParameters();
412

    
413
                // diferent column type
414
                if (attrOrg.getDataType() != attrTrg.getDataType()) {
415
                        strb = new StringBuilder();
416
                        strb.append("MODIFY (");
417
                        strb.append(helper.escapeFieldName(attrTrg.getName()));
418
                        strb.append(" ");
419
                        strb.append(helper.getSqlColumnTypeDescription(attrTrg));
420
                        strb.append(")");
421

    
422
                        if (attrOrg.getDataType().getType() == DataTypes.GEOMETRY) {
423
                                additionalStatement.add(getSqlGeometryFieldDrop(attrOrg));
424
                        }
425
                        if (attrTrg.getDataType().getType() == DataTypes.GEOMETRY) {
426
                                additionalStatement.addAll(((OracleHelper) helper)
427
                                                .getSqlGeometryFieldAdd(attrTrg, params.getTable(),
428
                                                                params.getSchema()));
429
                        }
430

    
431
                        actions.add(strb.toString());
432
                }
433

    
434
                if (attrOrg.allowNull() != attrTrg.allowNull()) {
435

    
436
                        strb = new StringBuilder();
437
                        strb.append("MODIFY (");
438
                        strb.append(helper.escapeFieldName(attrTrg.getName()));
439
                        strb.append(" ");
440
                        if (attrTrg.allowNull()) {
441
                                strb.append("SET ");
442
                        } else {
443
                                strb.append("DROP ");
444
                        }
445
                        strb.append("NOT NULL)");
446
                        actions.add(strb.toString());
447
                }
448

    
449
                if (attrOrg.getDefaultValue() != attrTrg.getDefaultValue()) {
450
                        if (attrTrg.getDefaultValue() == null) {
451

    
452
                                strb = new StringBuilder();
453
                                strb.append("MODIFY (");
454
                                strb.append(helper.escapeFieldName(attrTrg.getName()));
455
                                strb.append(" DROP DEFAULT)");
456
                                actions.add(strb.toString());
457
                        } else if (!attrTrg.getDefaultValue().equals(
458
                                        attrOrg.getDefaultValue())) {
459
                                // ALTER [ COLUMN ] column DROP DEFAULT
460

    
461
                                strb = new StringBuilder();
462
                                strb.append("MODIFY (");
463
                                strb.append(helper.escapeFieldName(attrTrg.getName()));
464
                                strb.append(" SET DEFAULT ");
465
                                strb.append(helper.dalValueToJDBC(attrTrg, attrTrg
466
                                                .getDefaultValue()));
467
                                strb.append(")");
468
                                actions.add(strb.toString());
469
                        }
470
                }
471

    
472
                if (attrOrg.getDataType() == attrTrg.getDataType()
473
                                && attrTrg.getDataType().getType() == DataTypes.GEOMETRY) {
474
                        // TODO Checks SRS and GeomType/Subtype
475
                }
476

    
477
                return actions;
478
        }
479

    
480
        private Object getSqlGeometryFieldDrop(FeatureAttributeDescriptor attr) {
481
                StringBuilder strb = new StringBuilder();
482
                OracleStoreParameters params = getOracleStoreParameters();
483
                
484
                strb.append("DELETE FROM ");
485
                strb.append(OracleValues.USER_ORACLE_GEOMETADATA_VIEW);
486
                strb.append(" WHERE ");
487
                strb.append(OracleValues.USER_ORACLE_GEOMETADATA_VIEW_TABLE_NAME);
488
                strb.append(" = '");
489
                strb.append(params.getTable());
490
                strb.append("' AND ");
491
                strb.append(OracleValues.USER_ORACLE_GEOMETADATA_VIEW_COLUMN_NAME);
492
                strb.append(" = '");
493
                strb.append(attr.getName());
494
                strb.append("'");
495

    
496
                return strb.toString();
497
        }
498
        
499
        
500
        protected void loadFeatureProviderValue(FeatureProvider data, ResultSet rs,
501
                        FeatureAttributeDescriptor attr) throws DataException {
502
                if (attr.getDataType().getType() == DataTypes.GEOMETRY) {
503

    
504
                        try {
505
                                Object geo_str_obj = rs.getObject(attr.getIndex() + 1);
506
                                if (geo_str_obj == null) {
507
                                        data.set(attr.getIndex(), OracleUtils.createNullGeometry(SUBTYPES.GEOM2D));
508
                                } else {
509
                                        STRUCT geo_str = (STRUCT) geo_str_obj;
510
                                        
511
                                        // IProjection proj = attr.getSRS();
512
                                        // OracleUtils.
513
                                        
514
                                        Geometry geom = OracleUtils.getGeometry(
515
                                                        geo_str,
516
                                                        false,
517
                                                        false,
518
                                                        "",
519
                                                        helper.getConnection());
520
                                        data.set(attr.getIndex(), geom);
521
                                }
522
                        } catch (SQLException e) {
523
                                throw new JDBCSQLException(e);
524
                        } catch (BaseException e) {
525
                                throw new ReadException(getName(), e);
526
                        }
527

    
528
                } else {
529
                        
530
                        try {
531
                                Object obj_data = rs.getObject(attr.getName());
532

    
533
                                if (obj_data != null) {
534
                                    obj_data = coerce(attr, obj_data);
535
                                }
536
                                
537
                                data.set(attr.getName(), obj_data);
538
                                
539
                                if (attr.isPrimaryKey()) {
540
                                        
541
                                        try {
542
                                                obj_data = getDataTypesManager().coerce(DataTypes.LONG, obj_data);
543
                                                data.setOID(obj_data);
544
                                        } catch (Exception ex) {
545
                                                logger.warn("Unable to convert OID to Long. Auto-increm will be used.");
546
                                        }
547

    
548
                                }
549
                        } catch (Exception e) {
550
                                throw new CreateFeatureException(e, NAME);
551
                        }
552
                }
553
        }
554
        
555
        
556
        
557
        /**
558
         * Load data form a resulset.<br>
559
         *
560
         * <strong>Note:</strong><br>
561
         * this method have to perform <code>resouceBegin</code> at the begining and
562
         * <code>resourceEnd</code> at the end of execution.
563
         *
564
         *
565
         * @param data
566
         * @param resulsetID
567
         *
568
         * @return
569
         * @throws DataException
570
         */
571
        public void loadFeatureProvider(final FeatureProvider data, final int resultsetID)
572
                        throws DataException {
573
                getResource().execute(new ResourceAction() {
574
                        public Object run() throws Exception {
575
                                ResultSet rs = getResultSet(resultsetID);
576
                                
577
                                FeatureAttributeDescriptor attr;
578
                                FeatureAttributeDescriptor[] atts = data.getType().getAttributeDescriptors();
579
                                int len = atts.length;
580
                                if (selectedFields == null){
581
                                    for (int i=0; i<len; i++) {
582
                                            attr = atts[i];
583
                                            loadFeatureProviderValue(data, rs, attr);
584
                                    }
585
                                }else{
586
                                    for (int i=0; i<len; i++) {
587
                        attr = atts[i];
588
                        if (selectedFields.containsKey(attr.getName())){
589
                            loadFeatureProviderValue(data, rs, attr);
590
                        }
591
                    }
592
                                }
593

    
594
                                // this should not happen, loadFeatureProviderValue checks PK
595
                                if (data.getOID() == null) {
596
                                        data.setOID(createNewOID());
597
                                }
598
                                return null;
599
                        }
600
                });
601
        }
602
        
603
        
604
        
605
        protected ResultSet createNewResultSet(final String sql,
606
                        final Object[] values, final int fetchSize)
607
                        throws DataException {
608
                this.open();
609
                return (ResultSet) getResource().execute(new ResourceAction() {
610
                        public Object run() throws Exception {
611
                                Connection conn = null;
612
                                PreparedStatement st = null;
613
                                ResultSet rs = null;
614
                                try {
615

    
616
                                        conn = helper.getConnection();
617
                                        conn.setAutoCommit(false);
618
                                        st = conn.prepareStatement(sql);
619

    
620
                                        if (values != null) {
621
                                                Object value;
622
                                                for (int i = 0; i < values.length; i++) {
623
                                                        value = values[i];
624
                                                        if (value instanceof Geometry) {
625
                                                                byte[] bytes;
626
                                                                try {
627
                                                                        bytes =
628
                                                                                        (byte[]) ((Geometry) value).invokeOperation(
629
                                                                                                        ToWKB.CODE, null);
630
                                                                } catch (BaseException e) {
631
                                                                        throw new InvalidParameterException();
632
                                                                }
633
                                                                st.setBytes(i + 1, bytes);
634
                                                        }
635
                                                        st.setObject(i + 1, value);
636
                                                }
637
                                        }
638

    
639
                                        if (fetchSize > 0) {
640
                                                st.setFetchSize(fetchSize);
641
                                        }
642
                                        rs = st.executeQuery();
643
                                        if (fetchSize > 0) {
644
                                                rs.setFetchSize(fetchSize);
645
                                        }
646
                                        return rs;
647
                                } catch (SQLException e) {
648
                                        try {
649
                                                rs.close();
650
                                        } catch (Exception e1) {
651
                                        }
652
                                        try {
653
                                                st.close();
654
                                        } catch (Exception e1) {
655
                                        }
656
                                        /*
657
                                        try {
658
                                                conn.close();
659
                                        } catch (Exception e1) {
660
                                        }
661
                                        */
662
                                        throw new JDBCExecutePreparedSQLException(sql,values,e);
663
                                }
664
                        }
665
                });
666
        }
667
        
668
        
669
        
670
        
671
        
672
        protected void closeResulset(final ResultSet rs) throws JDBCException,
673
        ResourceExecuteException {
674
                getResource().execute(new ResourceAction() {
675
                        public Object run() throws Exception {
676
                                Statement st = rs.getStatement();
677
                                Connection con = st.getConnection();
678
                                try {
679
                                        rs.close();
680
                                } finally {
681
                                        // TODO revisar esto
682
                                        try{ st.close();  } catch (Exception ex){ };
683
                                        // try{ con.close(); } catch (Exception ex){ };
684
                                }
685
                                return null;
686
                        }
687
                });
688
        }
689
        
690
        
691
        
692
        public String compoundSelect(FeatureType type, String filter, String order,
693
                        long limit, long offset) throws DataException {
694
                StringBuilder sql = new StringBuilder();
695
                JDBCStoreParameters params = getJDBCParameters();
696
                if (directSQLMode) {
697
                        sql.append(params.getSQL());
698
                        sql.append(' ');
699
                } else {
700
                    String sFields = (String)getParameters().getDynValue("fields");
701
            if (sFields == null){
702
                FeatureAttributeDescriptor[] fields = type
703
                .getAttributeDescriptors();
704

    
705
                // Select
706
                sql.append("Select ");
707
                for (int i = 0; i < fields.length - 1; i++) {
708
                    sql.append(helper.getSqlFieldName(fields[i]));
709
                    sql.append(", ");
710
                }
711

    
712
                sql.append(helper.getSqlFieldName(fields[fields.length - 1]));
713
                sql.append(' ');
714

    
715
                FeatureAttributeDescriptor[] pkFields = getStoreServices()
716
                .getProviderFeatureType(type.getId()).getPrimaryKey();
717

    
718
                if (pkFields != null && pkFields.length > 0) {
719
                    // checks for pk fields are in select
720
                    boolean toAdd;
721
                    for (int i = 0; i < pkFields.length; i++) {
722
                        toAdd = true;
723
                        for (int j = 0; j < fields.length; j++) {
724
                            if (pkFields[i].getName().equals(fields[j].getName())) {
725
                                toAdd = false;
726
                                break;
727
                            }
728
                            if (toAdd) {
729
                                sql.append(", ");
730
                                sql.append(helper.getSqlFieldName(pkFields[i]));
731
                            }
732
                        }
733
                    }
734
                    sql.append(' ');
735
                }
736
            }else{
737
                sql.append("Select ");
738
                sql.append(sFields);
739
                sql.append(' ');
740
            }
741

    
742
                        // table
743
                        sql.append("from ");
744
                        sql.append(params.tableID());
745
                        sql.append(' ');
746

    
747
                        // Where
748
                        appendWhere(sql, filter);
749

    
750
                        // Order
751
                        /*
752
                        if ((params.getBaseOrder() != null && params.getBaseOrder()
753
                                        .length() != 0)
754
                                        || (order != null && order.length() != 0)) {
755
                                sql.append("order by ");
756

757
                                if (order != null && order.length() != 0) {
758
                                        // order
759
                                        sql.append(order);
760
                                } else {
761
                                        // initial order
762
                                        sql.append(params.getBaseOrder());
763
                                }
764
                                sql.append(' ');
765
                        }
766
                        */
767
                }
768
                // limit offset
769
                /*
770
                if (limit > 0 || offset > 0) {
771
                        sql.append(helper.compoundLimitAndOffset(limit,offset));
772
                }^
773
                */
774
                logger.info("Executing SQL: " + sql.toString());
775
                return sql.toString();
776
        }
777
        
778
        private Object coerce(FeatureAttributeDescriptor att, Object v) throws CoercionException {
779
                
780
                if (!att.getObjectClass().isInstance(v)) {
781
                    
782
                    if (v instanceof TIMESTAMP && att.getDataType().getCoercion() instanceof CoerceToDateTime) {
783
                        
784
                        TIMESTAMP ora_ts = (TIMESTAMP) v;
785
                        try {
786
                            return ora_ts.timestampValue(); 
787
                        } catch (Exception ex) {
788
                            throw new CoercionException(ex);
789
                        }
790

    
791
                    } else {
792
                    return getDataTypesManager().coerce(att.getType(), v);
793
                    }
794
                    
795
                } else {
796
                        return v;
797
                }
798
        }
799
        
800
        private static DataTypesManager dtManager = null;
801
        
802
        
803
        protected DataTypesManager getDataTypesManager() {
804
                if( dtManager==null ) {
805
                        dtManager = ToolsLocator.getDataTypesManager();
806
                }
807
                return dtManager;
808
        }
809
        
810
        
811
        
812
        
813
        @Override
814
        protected FeatureProvider internalGetFeatureProviderByReference(
815
                        FeatureReferenceProviderServices reference,
816
                        FeatureType featureType)
817
                        throws DataException {
818
                StringBuilder filter = new StringBuilder();
819
                FeatureAttributeDescriptor[] pk =
820
                                getFeatureStore().getFeatureType(featureType.getId())
821
                                                .getPrimaryKey();
822

    
823
                List<Object> values = new ArrayList<Object>();
824

    
825
                int i;
826
                Object id_obj = null;
827
                
828
                // assumes PK with one component (Long) !!
829
                id_obj = OracleUtils.getId(reference, featureType);
830
                
831
                for (i = 0; i < pk.length - 1; i++) {
832
                        
833
                        
834
                        
835
                        values.add(
836
                                        helper.dalValueToJDBC(pk[i],
837
                                        id_obj));
838
                        filter.append(helper.getSqlFieldName(pk[i]));
839
                        filter.append(" = ? AND ");
840
                }
841
                
842
                values.add(helper.dalValueToJDBC(pk[i],
843
                                id_obj));
844
                filter.append(helper.getSqlFieldName(pk[i]));
845
                filter.append(" = ? ");
846

    
847
                String sql = compoundSelect(featureType, filter.toString(), null, 1, 0);
848

    
849
                FeatureProvider data;
850
                int rsId = createResultSet(sql, values.toArray(), 1);
851
                try {
852
                        if (!resulsetNext(rsId)) {
853
                                throw new RuntimeException("Reference Not found");
854
                        }
855
                        data = createFeatureProvider(featureType);
856
                        loadFeatureProvider(data, rsId);
857
                } finally {
858
                        closeResulset(rsId);
859
                }
860

    
861
                return data;
862
        }
863
    
864
        protected void executeRemovePreparedStatement(Connection conn, String sql,
865
            List<FeatureAttributeDescriptor> attributes, Iterator<FeatureReferenceProviderServices> featureReferences) throws DataException {
866
            PreparedStatement st;
867
            try {
868
                st = conn.prepareStatement(sql);
869
            } catch (SQLException e) {
870
                throw new JDBCPreparingSQLException(sql, e);
871
            }
872
            try {
873
                List<Object> values = new ArrayList<Object>();
874
                FeatureReferenceProviderServices featureRef;
875
                //              FeatureType featureType;
876
                while (featureReferences.hasNext()) {
877
                    st.clearParameters();
878
                    featureRef = featureReferences.next();
879
                    values.clear();                   
880

    
881
                    Iterator<FeatureAttributeDescriptor> iter = attributes.iterator();
882
                    FeatureAttributeDescriptor attr;
883
                    while (iter.hasNext()) {
884
                        attr =  iter.next();
885
                        if (attr.isPrimaryKey()){
886
                            values.add(helper.dalValueToJDBC(attr, featureRef.getFeature().get(attr.getIndex())));
887
                        }                       
888
                    }
889

    
890
                    for (int i = 0; i < values.size(); i++) {
891
                        st.setObject(i + 1, values.get(i));
892
                    }
893
                    try {
894
                        int nAffected =st.executeUpdate();
895
                        if (nAffected == 0) {
896
                            throw new JDBCUpdateWithoutChangesException(sql, values);
897
                        }
898
                        if (nAffected > 1){
899
                            logger.warn("Remove statement affectst to {} rows: {}",
900
                                nAffected, sql);
901
                        }
902

    
903
                    } catch (SQLException e) {
904
                        throw new JDBCExecutePreparedSQLException(sql, values, e);
905
                    }
906

    
907
                }
908
            } catch (SQLException e) {
909
                throw new JDBCSQLException(e);
910
            } finally {
911
                try {st.close();} catch (SQLException e) {  };
912
            }
913

    
914
        }
915
        
916
        
917
        
918

    
919
}