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 / JDBCStoreProviderBase.java @ 43020

History | View | Annotate | Download (16.3 KB)

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

    
3
import org.gvsig.fmap.dal.store.jdbc2.JDBCStoreProvider;
4
import java.util.Arrays;
5
import java.util.Collections;
6
import java.util.Iterator;
7
import java.util.List;
8
import org.cresques.cts.IProjection;
9
import org.gvsig.fmap.dal.DALLocator;
10
import org.gvsig.fmap.dal.DataManager;
11
import org.gvsig.fmap.dal.DataServerExplorer;
12
import org.gvsig.fmap.dal.DataStore;
13
import org.gvsig.fmap.dal.DataStoreNotification;
14
import org.gvsig.fmap.dal.DataTypes;
15
import org.gvsig.fmap.dal.exception.CloseException;
16
import org.gvsig.fmap.dal.exception.DataException;
17
import org.gvsig.fmap.dal.exception.InitializeException;
18
import org.gvsig.fmap.dal.exception.OpenException;
19
import org.gvsig.fmap.dal.exception.ReadException;
20
import org.gvsig.fmap.dal.feature.EditableFeatureType;
21
import org.gvsig.fmap.dal.feature.FeatureQuery;
22
import org.gvsig.fmap.dal.feature.FeatureRule;
23
import org.gvsig.fmap.dal.feature.FeatureRules;
24
import org.gvsig.fmap.dal.feature.FeatureType;
25
import org.gvsig.fmap.dal.feature.spi.AbstractFeatureStoreProvider;
26
import org.gvsig.fmap.dal.feature.spi.FeatureProvider;
27
import org.gvsig.fmap.dal.feature.spi.FeatureReferenceProviderServices;
28
import org.gvsig.fmap.dal.feature.spi.FeatureSetProvider;
29
import org.gvsig.fmap.dal.resource.spi.ResourceConsumer;
30
import org.gvsig.fmap.dal.resource.spi.ResourceProvider;
31
import org.gvsig.fmap.dal.spi.DataStoreProviderServices;
32
//import org.gvsig.fmap.dal.store.jdbc2.JDBCServerExplorerBase;
33
import org.gvsig.fmap.dal.store.jdbc.JDBCServerExplorerParameters;
34
import org.gvsig.fmap.dal.store.jdbc.JDBCStoreParameters;
35
import org.gvsig.fmap.dal.store.jdbc2.JDBCHelper;
36
import org.gvsig.fmap.dal.store.jdbc2.JDBCUtils;
37
import org.gvsig.fmap.dal.store.jdbc2.OperationsFactory;
38
import org.gvsig.fmap.dal.store.jdbc2.ResulSetControler;
39
import org.gvsig.fmap.dal.store.jdbc2.impl.JDBCSetProvider;
40
import org.gvsig.fmap.dal.store.jdbc2.spi.operations.AppendOperation;
41
import org.gvsig.fmap.dal.store.jdbc2.spi.operations.CalculateEnvelopeOfColumnOperation;
42
import org.gvsig.fmap.dal.store.jdbc2.spi.operations.CanModifyTableOperation;
43
import org.gvsig.fmap.dal.store.jdbc2.spi.operations.CountOperation;
44
import org.gvsig.fmap.dal.store.jdbc2.spi.operations.FetchFeatureProviderByReferenceOperation;
45
import org.gvsig.fmap.dal.store.jdbc2.spi.operations.FetchFeatureTypeOperation;
46
import org.gvsig.fmap.dal.store.jdbc2.spi.operations.PerformChangesOperation;
47
import org.gvsig.fmap.geom.primitive.Envelope;
48
import org.gvsig.tools.dynobject.DynObject;
49
import org.gvsig.tools.dynobject.exception.DynFieldNotFoundException;
50
import org.gvsig.tools.exception.BaseException;
51
import org.slf4j.Logger;
52
import org.slf4j.LoggerFactory;
53

    
54
public class JDBCStoreProviderBase
55
        extends AbstractFeatureStoreProvider
56
        implements ResourceConsumer, JDBCStoreProvider {
57

    
58
    final static private Logger logger = LoggerFactory.getLogger(JDBCStoreProviderBase.class);
59

    
60
    public class CountValue implements CalculatedValue<Long> {
61
        
62
        private Long value = null;
63

    
64
        @Override
65
        public void calculate() {
66
            JDBCStoreParameters params = getParameters();
67
            CountOperation count = getOperations().createCount(
68
                    params.getDBName(),
69
                    params.getSchema(),
70
                    params.getTable(),
71
                    params.getSQL(),
72
                    params.getBaseFilter(), 
73
                    null
74
            );
75
            this.value = (Long) count.perform();            
76
        }
77
        
78
        @Override
79
        public void reset() {
80
            this.value = null;
81
        }
82
        
83
        @Override
84
        public Long get() {
85
            if( this.value == null ) {
86
                this.calculate();
87
            }
88
            return this.value;
89
        }
90
    } 
91
    
92
    public class EnvelopeValue implements CalculatedValue<Envelope> {
93
        
94
        private Envelope value = null;
95

    
96
        @Override
97
        public void calculate() {
98
            try {
99
                String columnName = getFeatureStore()
100
                        .getDefaultFeatureType()
101
                        .getDefaultGeometryAttributeName();
102
                IProjection crs = getFeatureStore()
103
                        .getDefaultFeatureType()
104
                        .getDefaultSRS();
105
                JDBCStoreParameters params = getParameters();
106
                CalculateEnvelopeOfColumnOperation calculateEnvelopeOfColumn = 
107
                    getOperations().createCalculateEnvelopeOfColumn(
108
                        params.getSQL(), 
109
                        params.getDBName(),
110
                        params.getSchema(), 
111
                        params.getTable(), 
112
                        columnName, 
113
                        params.getBaseFilter(), 
114
                        params.getWorkingArea(), 
115
                        crs
116
                    );
117
                value = (Envelope) calculateEnvelopeOfColumn.perform();
118
            } catch(Exception ex) {
119
                throw new RuntimeException("Can't calculate envelope.", ex);
120
            }
121
        }
122
        
123
        @Override
124
        public void reset() {
125
            this.value = null;
126
        }
127
        
128
        @Override
129
        public Envelope get() {
130
            if( this.value == null ) {
131
                this.calculate();
132
            }
133
            return this.value;
134
        }
135
    } 
136
    
137
    public class AllowWriteValue implements CalculatedValue<Boolean> {
138
        
139
        private Boolean value = null;
140

    
141
        @Override
142
        public void calculate() {
143
            try {
144
                JDBCStoreParameters params = getParameters();
145
                CanModifyTableOperation canModifyTable = 
146
                    getOperations().createCanModifyTableOperation(
147
                        params.getDBName(),
148
                        params.getSchema(), 
149
                        params.getTable()
150
                    );
151
                this.value = (boolean) canModifyTable.perform();
152
            } catch(Exception ex) {
153
                throw new RuntimeException("Can't determine if allow write.", ex);
154
            }
155
        }
156
        
157
        @Override
158
        public void reset() {
159
            this.value = null;
160
        }
161
        
162
        @Override
163
        public Boolean get() {
164
            if( this.value == null ) {
165
                this.calculate();
166
            }
167
            return this.value;
168
        }
169
    } 
170
    
171
    protected final JDBCHelper helper;
172

    
173
    protected CalculatedValue<Long> count = null;
174
    
175
    protected CalculatedValue<Envelope> envelope = null;
176

    
177
    protected CalculatedValue<Boolean> allowWrite = null;
178

    
179
    protected AppendOperation appendOperation = null;
180
    
181
    protected JDBCStoreProviderBase(
182
            JDBCStoreParameters params,
183
            DataStoreProviderServices storeServices,
184
            DynObject metadata,
185
            JDBCHelper helper
186
    ) throws InitializeException {
187
        super(params, storeServices, metadata);
188
        this.helper = helper;
189
        this.initializeFeatureType();
190
    }
191

    
192
    
193
    @Override
194
    public JDBCSQLBuilderBase createExpressionBuilder() {
195
        return this.getHelper().createSQLBuilder();
196
    }
197

    
198
    @Override
199
    public JDBCStoreParameters getParameters() {
200
        return (JDBCStoreParameters) super.getParameters();
201
    }  
202

    
203
    @Override
204
    public JDBCHelper getHelper() {
205
        return helper;
206
    }
207
    
208
    public OperationsFactory getOperations() {
209
        return this.getHelper().getOperations();
210
    }
211
    
212
    @Override
213
    public String getProviderName() {
214
        return this.getHelper().getProviderName();
215
    }
216
    
217
    @Override
218
    public int getOIDType() {
219
        return DataTypes.UNKNOWN;
220
    }
221

    
222
    @Override
223
    public Object createNewOID() {
224
        return null;
225
    }
226
    
227
    @Override
228
    public boolean allowAutomaticValues() {
229
        return this.getHelper().allowAutomaticValues();
230
    }
231

    
232
    @Override
233
    public boolean allowWrite() {
234
        return this.getAllowWriteValue().get();
235
    }
236
    
237
    @Override
238
    public Object getDynValue(String name) throws DynFieldNotFoundException {
239
        try {
240
            if (DataStore.METADATA_ENVELOPE.equalsIgnoreCase(name)) {
241
                Envelope env = this.getEnvelope();
242
                if (env != null) {
243
                    return env;
244
                }
245
            } else if (DataStore.METADATA_CRS.equalsIgnoreCase(name)) {
246
                IProjection proj;
247
                proj = this.getFeatureStore().getDefaultFeatureType().getDefaultSRS();
248
                if (proj != null) {
249
                    return proj;
250
                }
251
            }
252
        } catch (DataException e) {
253
            throw new RuntimeException(e);
254
        }
255
        return super.getDynValue(name);
256
    }
257

    
258
    @Override
259
    public CalculatedValue<Long> getCountValue() {
260
        if( this.count == null ) {
261
            this.count = new CountValue();
262
        }
263
        return this.count;
264
    }
265

    
266
    @Override
267
    public CalculatedValue<Envelope> getEnvelopeValue() {
268
        if( this.envelope == null ) {
269
            this.envelope = new EnvelopeValue();
270
        }
271
        return this.envelope;
272
    }
273
    
274
    @Override
275
    public CalculatedValue<Boolean> getAllowWriteValue() {
276
        if( this.allowWrite == null ) {
277
            this.allowWrite = new AllowWriteValue();
278
        }
279
        return this.allowWrite;
280
    }
281
    
282
    @Override
283
    public long getFeatureCount() throws DataException {
284
        return this.getCountValue().get();
285
    }
286
    
287
    @Override
288
    public boolean closeResourceRequested(ResourceProvider resource) {
289
        ResulSetControler resulSetControler = this.getHelper().getResulSetControler();
290
        resulSetControler.pack();
291
        return resulSetControler.getOpenCount() == 0;
292
    }
293

    
294
    @Override
295
    public void close() throws CloseException {
296
        JDBCUtils.closeQuietly(this.getHelper());
297
    }
298

    
299
    @Override
300
    public void resourceChanged(ResourceProvider resource) {
301
        this.getStoreServices().notifyChange(
302
                DataStoreNotification.RESOURCE_CHANGED,
303
                resource
304
        );
305
    }
306

    
307
    @Override
308
    public DataServerExplorer getExplorer() throws ReadException {
309
        DataManager manager = DALLocator.getDataManager();
310
        JDBCServerExplorerParameters exParams;
311
        JDBCStoreParameters params = getParameters();
312
        try {
313
            exParams = this.getHelper().createServerExplorerParameters();
314
            exParams.setHost(params.getHost());
315
            exParams.setPort(params.getPort());
316
            exParams.setDBName(params.getDBName());
317
            exParams.setUser(params.getUser());
318
            exParams.setPassword(params.getPassword());
319
            exParams.setUrl(params.getUrl());
320
            exParams.setCatalog(params.getCatalog());
321
            exParams.setSchema(params.getSchema());
322
            exParams.setJDBCDriverClassName(params.getJDBCDriverClassName());
323

    
324
            return manager.openServerExplorer(exParams.getExplorerName(), exParams);
325
        } catch (Exception e) {
326
            throw new ReadException(this.getProviderName(), e);
327
        }
328
    }
329

    
330
    @Override
331
    protected void doDispose() throws BaseException {
332
        this.close();
333
        this.getHelper().dispose();
334
        super.doDispose();
335
    }
336

    
337
    @Override
338
    public String getSourceId() {
339
        return this.getHelper().getSourceId(this.getParameters());
340
    }
341

    
342
    @Override
343
    public String getName() {
344
        return this.getParameters().tableID();
345
    }
346

    
347
    @Override
348
    public String getFullName() {
349
        return this.getHelper().getSourceId(this.getParameters());
350
    }
351

    
352
    @Override
353
    public ResourceProvider getResource() {
354
        return getHelper().getResource();
355
    }
356

    
357
    @Override
358
    public void open() throws OpenException {
359

    
360
    }
361

    
362
    @Override
363
    public FeatureSetProvider createSet(
364
            FeatureQuery query,
365
            FeatureType featureType
366
        ) throws DataException {
367
        
368
        FeatureSetProvider set = new JDBCSetProvider(
369
                this,
370
                this.getHelper(), 
371
                query, 
372
                featureType
373
        );
374
        
375
        return set;
376
    }
377

    
378
    protected void initializeFeatureType() {
379
        EditableFeatureType type = this.getStoreServices().createFeatureType(getName());
380
        JDBCStoreParameters params = this.getParameters();
381
        List<String> primaryKeys = null;
382
        if( params.getPkFields() != null ) {
383
            primaryKeys = Arrays.asList(params.getPkFields());
384
        }
385
        FetchFeatureTypeOperation fetchFeatureType = 
386
             this.getOperations().createFetchFeatureType(
387
                type,
388
                params.getDBName(),
389
                params.getSchema(),
390
                params.getTable(),
391
                primaryKeys,
392
                params.getDefaultGeometryField(),
393
                params.getCRS()
394
            );
395
        fetchFeatureType.perform();
396

    
397
        FeatureType defaultType = type.getNotEditableCopy();
398
        List<FeatureType> types = Collections.singletonList(defaultType);
399
        this.getStoreServices().setFeatureTypes(types, defaultType);
400
    }
401
    
402
    @Override
403
    protected FeatureProvider internalGetFeatureProviderByReference(
404
            FeatureReferenceProviderServices reference, 
405
            FeatureType featureType
406
        ) throws DataException {
407
        JDBCStoreParameters params = this.getParameters();
408
        FetchFeatureProviderByReferenceOperation fetchFeatureProviderByReference = 
409
            this.getOperations().createFetchFeatureProviderByReference(
410
                reference, 
411
                featureType, 
412
                params.getDBName(),
413
                params.getSchema(), 
414
                params.getTable()
415
            );
416
        FeatureProvider feature = (FeatureProvider) fetchFeatureProviderByReference.perform();
417
        return feature;
418
    }
419
    
420
    @Override
421
    public Envelope getEnvelope() throws DataException {
422
        return this.getEnvelopeValue().get();
423
    }
424

    
425
    @Override
426
    public void performChanges(Iterator deleteds, Iterator inserteds,
427
                    Iterator updateds, Iterator featureTypesChanged)
428
                    throws DataException {
429

    
430
        FeatureType type = this.getFeatureStore().getDefaultFeatureType();
431
        JDBCStoreParameters params = this.getParameters();
432
        PerformChangesOperation performChanges = this.getOperations().createPerformChanges(
433
                params.getDBName(),
434
                params.getSchema(), 
435
                params.getTable(), 
436
                type, 
437
                deleteds, 
438
                inserteds, 
439
                updateds, 
440
                featureTypesChanged
441
        );
442
        performChanges.perform();
443
        if( performChanges.isTypeChanged() ) {
444
            // Get rules before initializing feature type
445
            FeatureRules saved_rules = getFeatureStore().getDefaultFeatureType().getRules();
446

    
447
             // This initialization loses the feature type rules
448
            this.initializeFeatureType();
449

    
450
            // Get new feature type, clear rules and add the ones saved previously
451
            FeatureType featureType = getFeatureStore().getDefaultFeatureType();
452
            FeatureRules rules = featureType.getRules();
453
            rules.clear();
454
            for (FeatureRule rule : saved_rules) {
455
                rules.add(rule);
456
            }
457
        }
458
        this.getCountValue().reset();
459
        this.getEnvelopeValue().reset();
460
    }    
461
    
462
    @Override
463
    public boolean supportsAppendMode() {
464
        return true;
465
    }
466

    
467
    protected AppendOperation getAppendOperation() throws DataException {
468
        if( this.appendOperation == null ) {
469
            FeatureType type = this.getFeatureStore().getDefaultFeatureType();
470
            JDBCStoreParameters params = this.getParameters();
471
            this.appendOperation = this.getOperations().createAppend(
472
                params.getDBName(),
473
                params.getSchema(), 
474
                params.getTable(), 
475
                type 
476
            );
477
        }
478
        return this.appendOperation;
479
    }
480
    
481
    @Override
482
    public void endAppend() throws DataException {
483
        this.getAppendOperation().end();
484
    }
485

    
486
    @Override
487
    public void beginAppend() throws DataException {
488
        this.getAppendOperation().begin();
489
    }
490

    
491
    @Override
492
    public void append(final FeatureProvider featureProvider) throws DataException {
493
        this.getAppendOperation().append(featureProvider);
494
    }    
495
    
496
    @Override
497
    public boolean canWriteGeometry(int geometryType, int geometrySubtype)
498
            throws DataException {
499
        return this.getHelper().canWriteGeometry(geometryType,geometrySubtype);
500
    }
501
}