Statistics
| Revision:

root / branches / v2_0_0_prep / libraries / libFMap_daldb / src / org / gvsig / fmap / dal / store / jdbc / JDBCStoreProvider.java @ 28424

History | View | Annotate | Download (11.5 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 IVER T.I   {{Task}}
26
*/
27

    
28
/**
29
 *
30
 */
31
package org.gvsig.fmap.dal.store.jdbc;
32

    
33
import java.sql.Connection;
34
import java.sql.ResultSet;
35
import java.sql.SQLException;
36
import java.sql.Statement;
37
import java.util.ArrayList;
38
import java.util.Iterator;
39
import java.util.List;
40

    
41
import org.gvsig.fmap.dal.DataServerExplorer;
42
import org.gvsig.fmap.dal.exception.CloseException;
43
import org.gvsig.fmap.dal.exception.DataException;
44
import org.gvsig.fmap.dal.exception.OpenException;
45
import org.gvsig.fmap.dal.exception.ReadException;
46
import org.gvsig.fmap.dal.feature.Feature;
47
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
48
import org.gvsig.fmap.dal.feature.FeatureQuery;
49
import org.gvsig.fmap.dal.feature.FeatureType;
50
import org.gvsig.fmap.dal.feature.exception.PerformEditingException;
51
import org.gvsig.fmap.dal.feature.spi.AbstractFeatureStoreProvider;
52
import org.gvsig.fmap.dal.feature.spi.FeatureData;
53
import org.gvsig.fmap.dal.feature.spi.FeatureReferenceProviderServices;
54
import org.gvsig.fmap.dal.feature.spi.FeatureSetProvider;
55
import org.gvsig.fmap.dal.resource.Resource;
56
import org.gvsig.fmap.dal.resource.exception.ResourceBeginException;
57
import org.gvsig.fmap.dal.resource.exception.ResourceNotifyCloseException;
58
import org.gvsig.fmap.dal.resource.spi.ResourceConsumer;
59
import org.gvsig.fmap.dal.resource.spi.ResourceProvider;
60
import org.gvsig.tools.persistence.PersistenceException;
61
import org.gvsig.tools.persistence.PersistentState;
62
import org.slf4j.Logger;
63
import org.slf4j.LoggerFactory;
64

    
65

    
66
/**
67
 * @author jmvivo
68
 *
69
 */
70
public abstract class JDBCStoreProvider extends AbstractFeatureStoreProvider
71
                implements ResourceConsumer {
72

    
73
        final static private Logger logger = LoggerFactory
74
                        .getLogger(JDBCStoreProvider.class);
75

    
76
        private List resulsetList;
77

    
78

    
79
        public JDBCStoreProvider() {
80
                super();
81
                resulsetList = new ArrayList(10);
82
        }
83

    
84
        /**
85
         * Permform a {@link Resource#begin()} to the current provider resources.
86
         *
87
         */
88
        protected abstract void resourceBegin() throws ResourceBeginException;
89

    
90
        /**
91
         * Permform a {@link Resource#end()} to the current provider resources.
92
         */
93
        protected abstract void resourceEnd();
94

    
95
        public abstract String compoundSelect(FeatureType type,
96
                        String filter,
97
                        String order,
98
                        long limit, long offset) throws DataException;
99

    
100
        /**
101
         * Get feature count for a <code>filter</code>.<br>
102
         *
103
         * <code>filter</code> can be <code>null</code>.<br>
104
         *
105
         * <strong>Note:</strong><br>
106
         * this method have to perform <code>resouceBegin</code> at the begining and
107
         * <code>resourceEnd</code> at the end of execution.
108
         *
109
         *
110
         * @param filter
111
         * @return
112
         * @throws DataException
113
         */
114
        protected abstract long getCount(String filter) throws DataException;
115

    
116
        /**
117
         * Load data form a resulset.<br>
118
         *
119
         * <strong>Note:</strong><br>
120
         * this method have to perform <code>resouceBegin</code> at the begining and
121
         * <code>resourceEnd</code> at the end of execution.
122
         *
123
         *
124
         * @param data
125
         * @param resulsetID
126
         *
127
         * @return
128
         * @throws DataException
129
         */
130
        public void loadFeatureData(FeatureData data, int resultsetID)
131
                        throws DataException {
132
                this.resourceBegin();
133
                try {
134
                        ResultSet rs = getResultSet(resultsetID);
135
                        FeatureAttributeDescriptor attr;
136
                        Iterator iter = data.getType().iterator();
137
                        while (iter.hasNext()) {
138
                                attr = (FeatureAttributeDescriptor) iter.next();
139
                                loadFeatureDataValue(data, rs, attr);
140
                        }
141
                } finally {
142
                        this.resourceEnd();
143
                }
144

    
145

    
146

    
147
        }
148

    
149
        protected void loadFeatureDataValue(FeatureData data, ResultSet rs,
150
                        FeatureAttributeDescriptor attr) throws DataException {
151

    
152
                try {
153
                        data.set(attr.getIndex(), rs.getObject(attr.getIndex() + 1));
154
                } catch (SQLException e) {
155
                        throw new JDBCSQLException(e);
156
                }
157

    
158
        }
159

    
160
        public final int createResultSet(String sql)
161
                        throws DataException {
162
                return createResultSet(sql, null);
163
        }
164

    
165
        public final int createResultSet(String sql, Object[] values)
166
                        throws DataException {
167
                synchronized (this) {
168
                        resourceBegin();
169
                        try {
170
                                ResultSet newRs = createNewResultSet(sql, values);
171
                                int newId = getNewId();
172
                                if (newId < 0) {
173
                                        newId = resulsetList.size();
174
                                        resulsetList.add(newRs);
175
                                } else {
176
                                        resulsetList.set(newId, newRs);
177
                                }
178
                                if (logger.isDebugEnabled()) {
179
                                        logger.debug(" id: " + newId + " (total "
180
                                                        + getResultsetOpenCount() + ")");
181
                                }
182

    
183
                                return newId;
184
                        } finally {
185
                                resourceEnd();
186
                        }
187

    
188
                }
189
        }
190

    
191
        protected abstract ResultSet createNewResultSet(String sql, Object[] values)
192
                        throws DataException;
193

    
194
        private int getNewId() {
195
                int newId;
196
                if (resulsetList.size() < 1) {
197
                        return -1;
198
                }
199
                for (newId = 0; newId < resulsetList.size(); newId++) {
200
                        if (resulsetList.get(newId) == null) {
201
                                return newId;
202
                        }
203
                }
204
                return -1;
205
        }
206

    
207
        protected final void forceCloseAllResultSet()
208
                        throws ResourceBeginException,
209
                        JDBCException {
210
                synchronized (this) {
211
                        Iterator iter = resulsetList.iterator();
212
                        Integer rsID = null;
213
                        while (iter.hasNext()) {
214
                                rsID = (Integer) iter.next();
215
                                if (rsID != null) {
216
                                        try {
217
                                                logger.warn("Close forced of resultSet ({})", rsID);
218
                                                closeResulset(rsID.intValue());
219
                                        } catch (InvalidResultSetIdException e) {
220
                                                continue;
221
                                        }
222
                                }
223
                                iter.remove();
224
                        }
225

    
226
                }
227

    
228
        }
229

    
230
        protected final ResultSet getResultSet(int resultsetID)
231
                        throws InvalidResultSetIdException {
232
                if (resultsetID >= resulsetList.size()) {
233
                        throw new InvalidResultSetIdException(resultsetID);
234
                }
235
                ResultSet rs = (ResultSet) resulsetList.get(resultsetID);
236
                if (rs == null) {
237
                        throw new InvalidResultSetIdException(resultsetID);
238
                }
239
                return rs;
240

    
241
        }
242

    
243
        private ResultSet dropResultSet(int resultsetID)
244
                        throws InvalidResultSetIdException {
245
                if (resultsetID >= resulsetList.size()) {
246
                        throw new InvalidResultSetIdException(resultsetID);
247
                }
248
                ResultSet rs = (ResultSet) resulsetList.get(resultsetID);
249
                if (rs == null) {
250
                        throw new InvalidResultSetIdException(resultsetID);
251
                }
252
                if (resultsetID == resulsetList.size() - 1) {
253
                        resulsetList.remove(resultsetID);
254
                } else {
255
                        resulsetList.set(resultsetID, null);
256
                }
257
                return rs;
258
        }
259

    
260

    
261
        public final boolean resulsetNext(int resultsetID) throws JDBCException,
262
                        InvalidResultSetIdException, ResourceBeginException {
263
                ResultSet rs = getResultSet(resultsetID);
264
                resourceBegin();
265
                try {
266
                        return rs.next();
267
                } catch (SQLException e) {
268
                        throw new JDBCSQLException(e);
269
                } finally {
270
                        resourceEnd();
271
                }
272
        }
273

    
274
        public final void closeResulset(int resultsetID)
275
                        throws JDBCException,
276
                        InvalidResultSetIdException, ResourceBeginException {
277
                synchronized (this) {
278
                        resourceBegin();
279
                        try {
280
                                ResultSet rs = dropResultSet(resultsetID);
281
                                closeResulset(rs);
282
                                if (logger.isDebugEnabled()) {
283
                                        logger.debug(" id: " + resultsetID + " (total "
284
                                                        + getResultsetOpenCount() + ")");
285
                                }
286

    
287
                        } finally {
288
                                resourceEnd();
289
                        }
290

    
291
                }
292
        }
293

    
294
        private int getResultsetOpenCount() {
295
                int count = 0;
296
                Iterator iter = resulsetList.iterator();
297
                while (iter.hasNext()) {
298
                        if (iter.next() != null) {
299
                                count++;
300
                        }
301
                }
302
                return count;
303
        }
304

    
305
        protected void closeResulset(ResultSet rs) throws JDBCException,
306
                        ResourceBeginException {
307
                resourceBegin();
308
                try {
309
                        Statement st = rs.getStatement();
310
                        Connection con = st.getConnection();
311
                        try {
312
                                rs.close();
313
                        } finally {
314
                                // TODO revisar esto
315
                                try{ st.close();  } catch (Exception ex){ };
316
                                try{ con.close(); } catch (Exception ex){ };
317
                        }
318
                } catch (SQLException e) {
319
                        throw new JDBCSQLException(e);
320
                } finally {
321
                        resourceEnd();
322
                }
323

    
324
        }
325

    
326
        protected final int openResulsetCount() {
327
                int count = 0;
328
                Iterator iter = resulsetList.iterator();
329
                while (iter.hasNext()) {
330
                        if (iter.next() != null) {
331
                                count++;
332
                        }
333
                }
334
                return count;
335
        }
336

    
337
        public boolean closeResourceRequested(ResourceProvider resource) {
338
                try {
339
                        return openResulsetCount() == 0 && closeResource(resource);
340
                } catch (ResourceNotifyCloseException e) {
341
                        return false;
342
                }
343
        }
344

    
345
        protected abstract boolean closeResource(ResourceProvider resource)
346
                        throws ResourceNotifyCloseException;
347

    
348
        public void dispose() throws CloseException {
349
                this.close();
350
                resulsetList = null;
351
                super.dispose();
352
        }
353

    
354
        public DataServerExplorer getExplorer() throws ReadException {
355
                // TODO Auto-generated method stub
356
                return null;
357
        }
358

    
359
        public void performEditing(Iterator deleteds, Iterator inserteds,
360
                        Iterator updateds, Iterator originalFeatureTypesUpdated) throws PerformEditingException {
361
                // TODO Auto-generated method stub
362

    
363
        }
364

    
365
        public PersistentState getState() throws PersistenceException {
366
                // TODO Auto-generated method stub
367
                return null;
368
        }
369

    
370
        public void loadState(PersistentState state) throws PersistenceException {
371
                // TODO Auto-generated method stub
372

    
373
        }
374

    
375
        public void setState(PersistentState state) throws PersistenceException {
376
                // TODO Auto-generated method stub
377

    
378
        }
379

    
380
        public Iterator getChilds() {
381
                // TODO Auto-generated method stub
382
                return null;
383
        }
384

    
385
        public Object getSourceId() {
386
                // TODO Auto-generated method stub
387
                return null;
388
        }
389

    
390
        public void open() throws OpenException {
391
                // TODO Auto-generated method stub
392

    
393
        }
394

    
395
        public void append(Feature feature) throws DataException {
396
                // TODO Auto-generated method stub
397

    
398
        }
399

    
400
        public void beginAppend() throws DataException {
401
                // TODO Auto-generated method stub
402

    
403
        }
404

    
405
        public boolean canWriteGeometry(int geometryType) throws DataException {
406
                // TODO Auto-generated method stub
407
                return false;
408
        }
409

    
410
        public Object createNewOID() {
411
                // TODO Auto-generated method stub
412
                return null;
413
        }
414

    
415
        public FeatureSetProvider createSet(FeatureQuery query,
416
                        FeatureType featureType) throws DataException {
417
                // TODO Auto-generated method stub
418
                return null;
419
        }
420

    
421
        public void endAppend() throws DataException {
422
                // TODO Auto-generated method stub
423

    
424
        }
425

    
426
        public FeatureData getFeatureDataByReference(
427
                        FeatureReferenceProviderServices reference, FeatureType featureType)
428
                        throws DataException {
429
                // TODO Auto-generated method stub
430
                return null;
431
        }
432

    
433
        public FeatureData getFeatureDataByReference(
434
                        FeatureReferenceProviderServices reference) throws DataException {
435
                // TODO Auto-generated method stub
436
                return null;
437
        }
438

    
439
        public int getFeatureReferenceOIDType() {
440
                // TODO Auto-generated method stub
441
                return 0;
442
        }
443

    
444
        public String getName() {
445
                // TODO Auto-generated method stub
446
                return null;
447
        }
448

    
449
        public boolean supportsAppendMode() {
450
                // TODO Auto-generated method stub
451
                return false;
452
        }
453

    
454
        public void resourceChanged(ResourceProvider resource) {
455
                // TODO Auto-generated method stub
456

    
457
        }
458

    
459
        public void close() throws CloseException {
460
                super.close();
461
                try {
462
                        resourceBegin();
463
                } catch (ResourceBeginException e) {
464
                        new CloseException(this.getName(), e);
465
                }
466
                try {
467
                        forceCloseAllResultSet();
468
                } catch (DataException e) {
469
                        new CloseException(this.getName(), e);
470
                } finally {
471
                        resourceEnd();
472
                }
473
        }
474

    
475
}