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

History | View | Annotate | Download (27.7 KB)

1
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright (C) 2007-2020 gvSIG Association.
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 3
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
 * For any additional information, do not hesitate to contact us
22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
23
 */
24
package org.gvsig.fmap.dal.store.jdbc2.spi;
25

    
26
import java.text.MessageFormat;
27
import java.util.Arrays;
28
import java.util.Collections;
29
import java.util.Iterator;
30
import java.util.List;
31
import org.apache.commons.lang3.BooleanUtils;
32
import org.apache.commons.lang3.StringUtils;
33
import org.apache.commons.lang3.builder.ToStringBuilder;
34
import org.cresques.cts.IProjection;
35
import org.gvsig.expressionevaluator.Expression;
36
import org.gvsig.fmap.dal.DALLocator;
37
import org.gvsig.fmap.dal.DataManager;
38
import org.gvsig.fmap.dal.DataServerExplorer;
39
import org.gvsig.fmap.dal.DataStore;
40
import org.gvsig.fmap.dal.DataStoreNotification;
41
import org.gvsig.fmap.dal.DataTypes;
42
import org.gvsig.fmap.dal.exception.CloseException;
43
import org.gvsig.fmap.dal.exception.DataException;
44
import org.gvsig.fmap.dal.exception.InitializeException;
45
import org.gvsig.fmap.dal.exception.OpenException;
46
import org.gvsig.fmap.dal.exception.ReadException;
47
import org.gvsig.fmap.dal.feature.EditableFeatureAttributeDescriptor;
48
import org.gvsig.fmap.dal.feature.EditableFeatureType;
49
import org.gvsig.fmap.dal.feature.FeatureQuery;
50
import org.gvsig.fmap.dal.feature.FeatureRule;
51
import org.gvsig.fmap.dal.feature.FeatureRules;
52
import org.gvsig.fmap.dal.feature.FeatureStore;
53
import org.gvsig.fmap.dal.feature.FeatureType;
54
import org.gvsig.fmap.dal.feature.spi.AbstractFeatureStoreProvider;
55
import org.gvsig.fmap.dal.feature.spi.FeatureProvider;
56
import org.gvsig.fmap.dal.feature.spi.FeatureReferenceProviderServices;
57
import org.gvsig.fmap.dal.feature.spi.FeatureSetProvider;
58
import org.gvsig.fmap.dal.resource.ResourceParameters;
59
import org.gvsig.fmap.dal.resource.exception.AccessResourceException;
60
import org.gvsig.fmap.dal.resource.exception.ResourceException;
61
import org.gvsig.fmap.dal.resource.spi.AbstractResource;
62
import org.gvsig.fmap.dal.resource.spi.ResourceConsumer;
63
import org.gvsig.fmap.dal.resource.spi.ResourceProvider;
64
import org.gvsig.fmap.dal.spi.DataStoreProviderServices;
65
import org.gvsig.fmap.dal.spi.DataTransactionServices;
66
import org.gvsig.fmap.dal.store.jdbc.JDBCServerExplorerParameters;
67
import org.gvsig.fmap.dal.store.jdbc.JDBCStoreParameters;
68
import org.gvsig.fmap.dal.store.jdbc2.JDBCHelper;
69
import org.gvsig.fmap.dal.store.jdbc2.JDBCStoreProvider;
70
import org.gvsig.fmap.dal.store.jdbc2.JDBCUtils;
71
import org.gvsig.fmap.dal.store.jdbc2.OperationsFactory;
72
import org.gvsig.fmap.dal.store.jdbc2.ResulSetControler;
73
import org.gvsig.fmap.dal.store.jdbc2.impl.JDBCSetProvider;
74
import org.gvsig.fmap.dal.store.jdbc2.spi.operations.AppendOperation;
75
import org.gvsig.fmap.dal.store.jdbc2.spi.operations.CalculateEnvelopeOfColumnOperation;
76
import org.gvsig.fmap.dal.store.jdbc2.spi.operations.CanModifyTableOperation;
77
import org.gvsig.fmap.dal.store.jdbc2.spi.operations.CountOperation;
78
import org.gvsig.fmap.dal.store.jdbc2.spi.operations.DeletePassThroughOperation;
79
import org.gvsig.fmap.dal.store.jdbc2.spi.operations.FetchFeatureProviderByReferenceOperation;
80
import org.gvsig.fmap.dal.store.jdbc2.spi.operations.FetchFeatureTypeOperation;
81
import org.gvsig.fmap.dal.store.jdbc2.spi.operations.PerformChangesOperation;
82
import org.gvsig.fmap.dal.store.jdbc2.spi.operations.UpdatePassThroughOperation;
83
import org.gvsig.fmap.geom.Geometry;
84
import org.gvsig.fmap.geom.primitive.Envelope;
85
import org.gvsig.tools.dynobject.DynField;
86
import org.gvsig.tools.dynobject.DynObject;
87
import org.gvsig.tools.dynobject.exception.DynFieldNotFoundException;
88
import org.gvsig.tools.exception.BaseException;
89
import org.gvsig.tools.observer.BaseNotification;
90
import org.gvsig.tools.observer.Observable;
91
import org.gvsig.tools.observer.Observer;
92
import org.slf4j.Logger;
93
import org.slf4j.LoggerFactory;
94

    
95
@SuppressWarnings("UseSpecificCatch")
96
public class JDBCStoreProviderBase
97
        extends AbstractFeatureStoreProvider
98
        implements ResourceConsumer, JDBCStoreProvider {
99

    
100
    final static protected Logger LOGGER = LoggerFactory.getLogger(JDBCStoreProviderBase.class);
101

    
102
    public class CountValue implements CalculatedValue<Long> {
103
        
104
        private Long value = null;
105

    
106
        @Override
107
        public void calculate() {
108
            try {
109
                JDBCStoreParameters params = getParameters();
110
                CountOperation count = getOperations().createCount(
111
                        getFeatureStore().getDefaultFeatureType(),
112
                        getOperations().createTableReference(params),
113
                        params.getBaseFilter(),
114
                        null
115
                );            
116
                this.value = (Long) count.perform();
117
            } catch (DataException ex) {
118
                throw new RuntimeException("Can't calculate count",ex);
119
            }
120
        }
121
        
122
        @Override
123
        public void reset() {
124
            this.value = null;
125
        }
126
        
127
        @Override
128
        public Long get() {
129
            if( this.value == null ) {
130
                this.calculate();
131
            }
132
            return this.value;
133
        }
134
    } 
135
    
136
    public class EnvelopeValue implements CalculatedValue<Envelope> {
137
        
138
        private Envelope value = null;
139
        private boolean needCalculate = true;
140

    
141
        @Override
142
        public void calculate() {
143
            FeatureStore featureStore;
144
            FeatureType featureType;
145
            try {
146
                featureStore = getFeatureStore();
147
                if (featureStore == null) {
148
                    return;
149
                }
150
                featureType = featureStore.getDefaultFeatureType();
151
                if (featureType == null) {
152
                    return;
153
                }
154
            } catch (Exception ex) {
155
                throw new RuntimeException("Can't calculate envelope.", ex);
156
            }
157
            try {
158
                value = null;
159
                String columnName = featureType.getDefaultGeometryAttributeName();
160
                if( columnName==null ) {
161
                    return;
162
                }
163
                IProjection crs = getFeatureStore()
164
                        .getDefaultFeatureType()
165
                        .getDefaultSRS();
166
                JDBCStoreParameters params = getParameters();
167
                CalculateEnvelopeOfColumnOperation calculateEnvelopeOfColumn = 
168
                    getOperations().createCalculateEnvelopeOfColumn(
169
                        getFeatureStore().getDefaultFeatureType(),
170
                        getOperations().createTableReference(params),
171
                        columnName, 
172
                        params.getBaseFilter(), 
173
                        params.getWorkingArea(), 
174
                        crs
175
                    );
176
                value = (Envelope) calculateEnvelopeOfColumn.perform();
177
                
178
            } catch(Throwable ex) {
179
                throw new RuntimeException("Can't calculate envelope.", ex);
180
            } finally {
181
               needCalculate = false;
182
            }
183
        }
184
        
185
        @Override
186
        public void reset() {
187
            this.value = null;
188
            this.needCalculate = true;
189
        }
190
        
191
        @Override
192
        public synchronized Envelope get() {
193
            if( needCalculate ) {
194
                this.calculate();
195
            }
196
            return this.value;
197
        }
198
    } 
199
        
200
    public class AllowWriteValue implements CalculatedValue<Boolean> {
201
        
202
        private Boolean value = null;
203

    
204
        @Override
205
        public void calculate() {
206
            try {
207
                JDBCStoreParameters params = getParameters();
208
                CanModifyTableOperation canModifyTable = 
209
                    getOperations().createCanModifyTableOperation(
210
                        getOperations().createTableReference(params)
211
                    );
212
                this.value = (boolean) canModifyTable.perform();
213
            } catch(Exception ex) {
214
                throw new RuntimeException("Can't determine if allow write.", ex);
215
            }
216
        }
217
        
218
        @Override
219
        public void reset() {
220
            this.value = null;
221
        }
222
        
223
        @Override
224
        public Boolean get() {
225
            if( this.value == null ) {
226
                this.calculate();
227
            }
228
            return this.value;
229
        }
230
    } 
231
    
232
    protected final JDBCHelper helper;
233

    
234
    protected CalculatedValue<Long> count = null;
235
    
236
    protected CalculatedValue<Envelope> envelope = null;
237

    
238
    protected CalculatedValue<Boolean> allowWrite = null;
239

    
240
    protected AppendOperation appendOperation = null;
241
    
242
    protected Observer transactionObserver;
243
    
244
    @SuppressWarnings({"OverridableMethodCallInConstructor", "CallToThreadStartDuringObjectConstruction"})
245
    protected JDBCStoreProviderBase(
246
            JDBCStoreParameters params,
247
            DataStoreProviderServices storeServices,
248
            DynObject metadata,
249
            JDBCHelper helper
250
    ) throws InitializeException {
251
        super(params, storeServices, metadata);
252
        this.helper = helper;
253
        this.initializeFeatureType();
254
        try {
255
            if( BooleanUtils.isTrue((Boolean) params.getDynValue("precalculateEnvelope"))  ) {
256
                FeatureType featureType = this.getStoreServices().getDefaultFeatureType();
257
                if( !StringUtils.isEmpty(featureType.getDefaultGeometryAttributeName()) ) {
258
                    Thread thread = new Thread(() -> {
259
                        LOGGER.trace("Precalculating envelope of '"+getSourceId()+"'.");
260
                        getEnvelopeValue().get();
261
                    }, "PrecalculateEnvelopeOfDBTable");
262
                    thread.start();
263
                    Thread.sleep(1);
264
                }
265
           }
266
        } catch(Exception ex) {
267
            LOGGER.warn("Probems precalculating the envelope of table '"+this.getSourceId()+"'.", ex);
268
        }
269
        this.transactionObserver = new Observer() {
270
            @Override
271
            public void update(Observable o, Object o1) {
272
                if( o1 instanceof BaseNotification && (
273
                        ((BaseNotification)o1).isOfType("ROLLBACK") ||
274
                        ((BaseNotification)o1).isOfType("COMMIT")
275
                        ) ) {
276
                    getCountValue().reset();
277
                    getEnvelopeValue().reset();
278
                }
279
            }
280
        };
281
    }
282

    
283
    @Override
284
    public JDBCStoreParameters getParameters() {
285
        return (JDBCStoreParameters) super.getParameters();
286
    }  
287

    
288
    @Override
289
    public JDBCHelper getHelper() {
290
        return helper;
291
    }
292
    
293
    public OperationsFactory getOperations() {
294
        return this.getHelper().getOperations();
295
    }
296
    
297
    @Override
298
    public String getProviderName() {
299
        return this.getHelper().getProviderName();
300
    }
301
    
302
    @Override
303
    public int getOIDType() {
304
        return DataTypes.UNKNOWN;
305
    }
306

    
307
    @Override
308
    public Object createNewOID() {
309
        return null;
310
    }
311
    
312
    @Override
313
    public boolean allowAutomaticValues() {
314
        return this.getHelper().allowAutomaticValues();
315
    }
316

    
317
    @Override
318
    public boolean allowWrite() {
319
        return this.getAllowWriteValue().get();
320
    }
321
    
322
    @Override
323
    public Object getDynValue(String name) throws DynFieldNotFoundException {
324
        try {
325
            if (DataStore.METADATA_ENVELOPE.equalsIgnoreCase(name)) {
326
                Envelope env = this.getEnvelope();
327
                if (env != null) {
328
                    return env;
329
                }
330
            } else if (DataStore.METADATA_CRS.equalsIgnoreCase(name)) {
331
                IProjection proj;
332
                proj = this.getFeatureStore().getDefaultFeatureType().getDefaultSRS();
333
                if (proj != null) {
334
                    return proj;
335
                }
336
            }
337
        } catch (DataException e) {
338
            throw new RuntimeException(e);
339
        }
340
        return super.getDynValue(name);
341
    }
342

    
343
    @Override
344
    public CalculatedValue<Long> getCountValue() {
345
        if( this.count == null ) {
346
            this.count = new CountValue();
347
        }
348
        return this.count;
349
    }
350

    
351
    @Override
352
    public CalculatedValue<Envelope> getEnvelopeValue() {
353
        if( this.envelope == null ) {
354
            this.envelope = new EnvelopeValue();
355
        }
356
        return this.envelope;
357
    }
358
    
359
    @Override
360
    public CalculatedValue<Boolean> getAllowWriteValue() {
361
        if( this.allowWrite == null ) {
362
            this.allowWrite = new AllowWriteValue();
363
        }
364
        return this.allowWrite;
365
    }
366
    
367
    @Override
368
    public long getFeatureCount() throws DataException {
369
        return this.getCountValue().get();
370
    }
371
    
372
    @Override
373
    public boolean closeResourceRequested(ResourceProvider resource) {
374
        ResulSetControler resulSetControler = this.getHelper().getResulSetControler();
375
        resulSetControler.pack();
376
        return resulSetControler.getOpenCount() == 0;
377
    }
378

    
379
    @Override
380
    public void close() throws CloseException {
381
        JDBCUtils.closeQuietly(this.getHelper());
382
    }
383

    
384
    @Override
385
    public void resourceChanged(ResourceProvider resource) {
386
        this.getStoreServices().notifyChange(
387
                DataStoreNotification.RESOURCE_CHANGED,
388
                resource
389
        );
390
    }
391

    
392
    @Override
393
    public DataServerExplorer getExplorer() throws ReadException {
394
        DataManager manager = DALLocator.getDataManager();
395
        JDBCServerExplorerParameters exParams;
396
        JDBCStoreParameters params = getParameters();
397
        try {
398
            exParams = this.getHelper().createServerExplorerParameters();
399
            DynField[] fields = exParams.getDynClass().getDynFields();
400
            for (DynField field : fields) {
401
                try {
402
                    exParams.setDynValue(field.getName(), params.getDynValue(field.getName()));
403
                } catch(Exception ex) {
404
                    // Ignore
405
                }
406
            }
407
            exParams.setHost(params.getHost());
408
            exParams.setPort(params.getPort());
409
            exParams.setDBName(params.getDBName());
410
            exParams.setUser(params.getUser());
411
            exParams.setPassword(params.getPassword());
412
            exParams.setUrl(params.getUrl());
413
            exParams.setCatalog(params.getCatalog());
414
            exParams.setSchema(params.getSchema());
415
            exParams.setJDBCDriverClassName(params.getJDBCDriverClassName());
416

    
417
            return manager.openServerExplorer(exParams.getExplorerName(), exParams);
418
        } catch (Exception e) {
419
            throw new ReadException(this.getProviderName(), e);
420
        }
421
    }
422

    
423
    @Override
424
    protected void doDispose() throws BaseException {
425
        if( this.helper.getTransaction()!=null ) {
426
            this.helper.getTransaction().deleteObserver(transactionObserver);
427
        }
428
        this.close();
429
        this.getHelper().dispose();
430
        super.doDispose();
431
    }
432

    
433
    @Override
434
    public String getSourceId() {
435
        try {
436
            return this.getHelper().getSourceId(this.getParameters());
437
        } catch(Exception ex) {
438
            return "unknow";
439
        }
440
    }
441

    
442
    @Override
443
    public String getName() {
444
        return this.getParameters().getTable();
445
    }
446

    
447
    @Override
448
    public String getFullName() {
449
        return this.getHelper().getSourceId(this.getParameters());
450
    }
451

    
452
    private static class DummyResource extends AbstractResource {
453

    
454
        private final String name;
455

    
456
        DummyResource(String name) throws InitializeException {
457
            super((ResourceParameters)null);
458
            this.name = name;
459
        }
460
        
461
        @Override
462
        public String getName() throws AccessResourceException {
463
            return MessageFormat.format("DummyResource({0})",
464
                                new Object[] { this.name });
465
        }
466

    
467
        @Override
468
        public Object get() throws AccessResourceException {
469
            return null;
470
        }
471

    
472
        @Override
473
        public boolean isThis(ResourceParameters parameters) throws ResourceException {
474
            return true;
475
        }
476
        
477
    }
478
    
479
    @Override
480
    public ResourceProvider getResource() {
481
        ResourceProvider r = getHelper().getResource();
482
        if( r == null ) {
483
            try {
484
                r = new DummyResource(this.getName());
485
            } catch (InitializeException ex) {
486
                LOGGER.warn("Can't create DummyResource",ex);
487
                // Do nothing
488
            }
489
        }
490
        return r;
491
    }
492

    
493
    @Override
494
    public void open() throws OpenException {
495

    
496
    }
497

    
498
    @Override
499
    public FeatureSetProvider createSet(
500
            FeatureQuery query,
501
            FeatureType featureType
502
        ) throws DataException {
503
        
504
        FeatureSetProvider set = new JDBCSetProvider(
505
                this,
506
                this.getHelper(), 
507
                query, 
508
                featureType
509
        );
510
        
511
        return set;
512
    }
513

    
514
    protected void initializeFeatureType() {
515
        EditableFeatureType type = this.getStoreServices().createFeatureType(getName());
516
        JDBCStoreParameters params = this.getParameters();
517
        List<String> primaryKeys = null;
518
        if( params.getPkFields() != null ) {
519
            primaryKeys = Arrays.asList(params.getPkFields());
520
        }
521
        FetchFeatureTypeOperation fetchFeatureType = 
522
             this.getOperations().createFetchFeatureType(
523
                type,
524
                this.getOperations().createTableReference(params),
525
                primaryKeys,
526
                params.getDefaultGeometryField(),
527
                params.getCRS(),
528
                params.getGeometryType(),
529
                params.getGeometrySubtype()
530
            );
531
        fetchFeatureType.perform();
532

    
533
        if (!StringUtils.isBlank(params.getDefaultGeometryField())) {
534
            if (!params.getDefaultGeometryField().equalsIgnoreCase(type.getDefaultGeometryAttributeName())) {
535
                if (type.getAttributeDescriptor(params.getDefaultGeometryField()) != null) {
536
                    type.setDefaultGeometryAttributeName(params.getDefaultGeometryField());
537
                } else {
538
                    type.setDefaultGeometryAttributeName(null);
539
                }
540
                if (type.getDefaultGeometryAttribute() != null) {
541
                    EditableFeatureAttributeDescriptor attr = (EditableFeatureAttributeDescriptor) type.getDefaultGeometryAttribute();
542
                    attr.setGeometryType(Geometry.TYPES.GEOMETRY, Geometry.SUBTYPES.GEOM2D);
543
                }
544
            } else {
545
                type.setDefaultGeometryAttributeName(null);
546
            }
547
        }
548
        
549
        FeatureType defaultType = type.getNotEditableCopy();
550
        this.getHelper().setProviderFeatureType(defaultType);
551
        List<FeatureType> types = Collections.singletonList(defaultType);
552
        this.getStoreServices().setFeatureTypes(types, defaultType);
553
    }
554

    
555
    @Override
556
    protected FeatureProvider internalGetFeatureProviderByReference(
557
            FeatureReferenceProviderServices reference, 
558
            FeatureType featureType
559
        ) throws DataException {
560
        JDBCStoreParameters params = this.getParameters();
561
        FetchFeatureProviderByReferenceOperation fetchFeatureProviderByReference = 
562
            this.getOperations().createFetchFeatureProviderByReference(
563
                reference, 
564
                featureType, 
565
                this.getOperations().createTableReference(params)
566
            );
567
        FeatureProvider feature = (FeatureProvider) fetchFeatureProviderByReference.perform();
568
        return feature;
569
    }
570
    
571
    @Override
572
    public Envelope getEnvelope() throws DataException {
573
        return this.getEnvelopeValue().get();
574
    }
575

    
576
    @Override
577
    public void performChanges(Iterator deleteds, Iterator inserteds,
578
                    Iterator updateds, Iterator featureTypesChanged)
579
                    throws DataException {
580

    
581
        FeatureType type = this.getFeatureStore().getDefaultFeatureType();
582
        JDBCStoreParameters params = this.getParameters();
583
        PerformChangesOperation performChanges = this.getOperations().createPerformChanges(
584
                this.getOperations().createTableReference(params),
585
                type, 
586
                deleteds, 
587
                inserteds, 
588
                updateds, 
589
                featureTypesChanged,
590
                this.getStoreServices()
591
        );
592
        performChanges.perform();
593
        if( performChanges.isTypeChanged() ) {
594
            // Get rules before initializing feature type
595
            FeatureRules saved_rules = getFeatureStore().getDefaultFeatureType().getRules();
596

    
597
             // This initialization loses the feature type rules
598
            this.initializeFeatureType();
599

    
600
            // Get new feature type, clear rules and add the ones saved previously
601
            FeatureType featureType = getFeatureStore().getDefaultFeatureType();
602
            FeatureRules rules = featureType.getRules();
603
            rules.clear();
604
            for (FeatureRule rule : saved_rules) {
605
                rules.add(rule);
606
            }
607
        }
608
        this.getCountValue().reset();
609
        this.getEnvelopeValue().reset();
610
    }    
611
    
612
    @Override
613
    public boolean supportsAppendMode() {
614
        return true;
615
    }
616

    
617
    protected AppendOperation createAppendOperation() throws DataException {
618
        FeatureType type = this.getFeatureStore().getDefaultFeatureType();
619
        JDBCStoreParameters params = this.getParameters();
620
        AppendOperation theAppendOperation = this.getOperations().createAppend(
621
                this.getOperations().createTableReference(params),
622
                type 
623
        );
624
        return theAppendOperation;
625
    }
626
    
627
    @Override
628
    public void endAppend() throws DataException {
629
        this.appendOperation.end();
630
        this.getCountValue().reset();
631
        this.getEnvelopeValue().reset();
632
    }
633

    
634
    @Override
635
    public void abortAppend() throws DataException {
636
        this.appendOperation.abort();
637
    }
638
    
639
    @Override
640
    public void beginAppend() throws DataException {
641
        if( this.appendOperation == null ) {
642
            this.appendOperation = createAppendOperation();
643
        }
644
        this.appendOperation.begin();
645
    }
646

    
647
    @Override
648
    public void append(final FeatureProvider featureProvider) throws DataException {
649
        this.appendOperation.append(featureProvider);
650
    }    
651
    
652
    @Override
653
    public boolean canWriteGeometry(int geometryType, int geometrySubtype)
654
            throws DataException {
655
        return this.getHelper().canWriteGeometry(geometryType,geometrySubtype);
656
    }
657

    
658
    @Override
659
    public boolean supportsPassThroughMode() {
660
        return true;
661
    }
662

    
663
    @Override
664
    public void passThroughInsert(FeatureProvider featureProvider) throws DataException {
665
        FeatureType type = this.getFeatureStore().getDefaultFeatureType();
666
        JDBCStoreParameters params = this.getParameters();
667
        PerformChangesOperation performChanges = this.getOperations().createPerformChanges(
668
                this.getOperations().createTableReference(params),
669
                type, 
670
                Collections.emptyIterator(), 
671
                Collections.singletonList(featureProvider).iterator(),
672
                Collections.emptyIterator(), 
673
                Collections.emptyIterator(),
674
                this.getStoreServices()
675
        );
676
        performChanges.perform();
677
        this.getCountValue().reset();
678
        this.getEnvelopeValue().reset();
679
    }
680

    
681
    @Override
682
    public void passThroughUpdate(FeatureProvider featureProvider) throws DataException {
683
        FeatureType type = this.getFeatureStore().getDefaultFeatureType();
684
        JDBCStoreParameters params = this.getParameters();
685
        PerformChangesOperation performChanges = this.getOperations().createPerformChanges(
686
                this.getOperations().createTableReference(params),
687
                type, 
688
                Collections.emptyIterator(), 
689
                Collections.emptyIterator(), 
690
                Collections.singletonList(featureProvider).iterator(),
691
                Collections.emptyIterator(),
692
                this.getStoreServices()
693
        );
694
        performChanges.perform();
695
//        this.getCountValue().reset();
696
        this.getEnvelopeValue().reset();
697
    }
698
    
699
    @Override
700
    public void passThroughUpdate(Object[] parameters, Expression filter){
701
        JDBCStoreParameters params = this.getParameters();
702
        UpdatePassThroughOperation operation = this.getOperations().createUpdatePassThroughOperation(
703
                this.getOperations().createTableReference(params),
704
                parameters,
705
                filter
706
        );
707
        operation.perform();
708
//        this.getCountValue().reset();
709
        this.getEnvelopeValue().reset();
710
    }
711

    
712
    @Override
713
    public void passThroughDelete(FeatureReferenceProviderServices featureReference) throws DataException {
714
        FeatureType type = this.getFeatureStore().getDefaultFeatureType();
715
        JDBCStoreParameters params = this.getParameters();
716
        PerformChangesOperation performChanges = this.getOperations().createPerformChanges(
717
                this.getOperations().createTableReference(params),
718
                type, 
719
                Collections.singletonList(featureReference).iterator(),
720
                Collections.emptyIterator(), 
721
                Collections.emptyIterator(), 
722
                Collections.emptyIterator(),
723
                this.getStoreServices()
724
        );
725
        performChanges.perform();
726
        this.getCountValue().reset();
727
        this.getEnvelopeValue().reset();
728
    }
729
    
730
    @Override
731
    public void passThroughDelete(Expression expression) throws DataException {
732
        JDBCStoreParameters params = this.getParameters();
733
        DeletePassThroughOperation operation = this.getOperations().createDeletePassThroughOperation(
734
                this.getOperations().createTableReference(params),
735
                expression
736
        );
737
        operation.perform();
738
        this.getCountValue().reset();
739
        this.getEnvelopeValue().reset();
740
    }
741

    
742
    @Override
743
    public void setTransaction(DataTransactionServices transaction) {
744
        if( this.helper.getTransaction()!=null ) {
745
            this.helper.getTransaction().deleteObserver(transactionObserver);
746
        }
747
        this.helper.setTransaction(transaction);
748
        if( transaction!=null ) {
749
            transaction.addObserver(transactionObserver);
750
        }
751
    }
752
    
753
    @Override
754
    public String toString() {
755
        try {
756
            ToStringBuilder builder = new ToStringBuilder(this);
757
            builder.append("hash", String.format("%x", this.hashCode()));
758
            builder.append("helper", this.helper, true);
759
            return builder.toString();
760
        } catch (Exception e) {
761
            return super.toString();
762
        }
763
    }
764

    
765
    @Override
766
    public void refresh() throws OpenException {
767
        // Force to recalculare count, envelope and allowWrite
768
        this.count = null;
769
        this.envelope = null;
770
        this.allowWrite = null;
771
//        
772
//        if( this.helper.getResulSetControler().getOpenCount()>0 ) {
773
//            // Has ResultSetEntry open. Oh!!!!
774
//            this.helper.getResulSetControler().closeAll();
775
//        }
776
//        if( this.appendOperation!=null ) {
777
//            // Has and append operation in progress, Oh!!
778
//            this.appendOperation.abort();
779
//            this.appendOperation = null;
780
//        }
781
        super.refresh(); 
782
    }
783
    
784
}