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

History | View | Annotate | Download (29.9 KB)

1 45065 jjdelcerro
/**
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 43020 jjdelcerro
package org.gvsig.fmap.dal.store.jdbc2.spi;
25
26 43409 jjdelcerro
import java.text.MessageFormat;
27 43020 jjdelcerro
import java.util.Arrays;
28
import java.util.Collections;
29
import java.util.Iterator;
30
import java.util.List;
31 43361 jjdelcerro
import org.apache.commons.lang3.BooleanUtils;
32
import org.apache.commons.lang3.StringUtils;
33 47198 jjdelcerro
import org.apache.commons.lang3.builder.ToStringBuilder;
34 43020 jjdelcerro
import org.cresques.cts.IProjection;
35 45425 jjdelcerro
import org.gvsig.expressionevaluator.Expression;
36 43020 jjdelcerro
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 47606 fdiaz
import org.gvsig.fmap.dal.DataTransaction;
42 43020 jjdelcerro
import org.gvsig.fmap.dal.DataTypes;
43
import org.gvsig.fmap.dal.exception.CloseException;
44
import org.gvsig.fmap.dal.exception.DataException;
45
import org.gvsig.fmap.dal.exception.InitializeException;
46
import org.gvsig.fmap.dal.exception.OpenException;
47
import org.gvsig.fmap.dal.exception.ReadException;
48 47485 fdiaz
import org.gvsig.fmap.dal.expressionevaluator.FeatureAttributeEmulatorExpression;
49 43420 jjdelcerro
import org.gvsig.fmap.dal.feature.EditableFeatureAttributeDescriptor;
50 43020 jjdelcerro
import org.gvsig.fmap.dal.feature.EditableFeatureType;
51 47485 fdiaz
import org.gvsig.fmap.dal.feature.Feature;
52
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
53
import org.gvsig.fmap.dal.feature.FeatureAttributeEmulator;
54 43020 jjdelcerro
import org.gvsig.fmap.dal.feature.FeatureQuery;
55
import org.gvsig.fmap.dal.feature.FeatureRule;
56
import org.gvsig.fmap.dal.feature.FeatureRules;
57 47485 fdiaz
import org.gvsig.fmap.dal.feature.FeatureSet;
58 45581 fdiaz
import org.gvsig.fmap.dal.feature.FeatureStore;
59 43020 jjdelcerro
import org.gvsig.fmap.dal.feature.FeatureType;
60
import org.gvsig.fmap.dal.feature.spi.AbstractFeatureStoreProvider;
61
import org.gvsig.fmap.dal.feature.spi.FeatureProvider;
62
import org.gvsig.fmap.dal.feature.spi.FeatureReferenceProviderServices;
63
import org.gvsig.fmap.dal.feature.spi.FeatureSetProvider;
64 43409 jjdelcerro
import org.gvsig.fmap.dal.resource.ResourceParameters;
65
import org.gvsig.fmap.dal.resource.exception.AccessResourceException;
66
import org.gvsig.fmap.dal.resource.exception.ResourceException;
67
import org.gvsig.fmap.dal.resource.spi.AbstractResource;
68 43020 jjdelcerro
import org.gvsig.fmap.dal.resource.spi.ResourceConsumer;
69
import org.gvsig.fmap.dal.resource.spi.ResourceProvider;
70
import org.gvsig.fmap.dal.spi.DataStoreProviderServices;
71 45650 jjdelcerro
import org.gvsig.fmap.dal.spi.DataTransactionServices;
72 43020 jjdelcerro
import org.gvsig.fmap.dal.store.jdbc.JDBCServerExplorerParameters;
73
import org.gvsig.fmap.dal.store.jdbc.JDBCStoreParameters;
74
import org.gvsig.fmap.dal.store.jdbc2.JDBCHelper;
75 45614 fdiaz
import org.gvsig.fmap.dal.store.jdbc2.JDBCStoreProvider;
76 43020 jjdelcerro
import org.gvsig.fmap.dal.store.jdbc2.JDBCUtils;
77
import org.gvsig.fmap.dal.store.jdbc2.OperationsFactory;
78
import org.gvsig.fmap.dal.store.jdbc2.ResulSetControler;
79
import org.gvsig.fmap.dal.store.jdbc2.impl.JDBCSetProvider;
80
import org.gvsig.fmap.dal.store.jdbc2.spi.operations.AppendOperation;
81
import org.gvsig.fmap.dal.store.jdbc2.spi.operations.CalculateEnvelopeOfColumnOperation;
82
import org.gvsig.fmap.dal.store.jdbc2.spi.operations.CanModifyTableOperation;
83
import org.gvsig.fmap.dal.store.jdbc2.spi.operations.CountOperation;
84 45473 fdiaz
import org.gvsig.fmap.dal.store.jdbc2.spi.operations.DeletePassThroughOperation;
85 43020 jjdelcerro
import org.gvsig.fmap.dal.store.jdbc2.spi.operations.FetchFeatureProviderByReferenceOperation;
86
import org.gvsig.fmap.dal.store.jdbc2.spi.operations.FetchFeatureTypeOperation;
87
import org.gvsig.fmap.dal.store.jdbc2.spi.operations.PerformChangesOperation;
88 45473 fdiaz
import org.gvsig.fmap.dal.store.jdbc2.spi.operations.UpdatePassThroughOperation;
89 43420 jjdelcerro
import org.gvsig.fmap.geom.Geometry;
90 47485 fdiaz
import org.gvsig.fmap.geom.GeometryUtils;
91 43020 jjdelcerro
import org.gvsig.fmap.geom.primitive.Envelope;
92 44185 jjdelcerro
import org.gvsig.tools.dynobject.DynField;
93 43020 jjdelcerro
import org.gvsig.tools.dynobject.DynObject;
94
import org.gvsig.tools.dynobject.exception.DynFieldNotFoundException;
95
import org.gvsig.tools.exception.BaseException;
96 46315 jjdelcerro
import org.gvsig.tools.observer.BaseNotification;
97
import org.gvsig.tools.observer.Observable;
98
import org.gvsig.tools.observer.Observer;
99 43020 jjdelcerro
import org.slf4j.Logger;
100
import org.slf4j.LoggerFactory;
101
102 44058 jjdelcerro
@SuppressWarnings("UseSpecificCatch")
103 43020 jjdelcerro
public class JDBCStoreProviderBase
104
        extends AbstractFeatureStoreProvider
105
        implements ResourceConsumer, JDBCStoreProvider {
106
107 45614 fdiaz
    final static protected Logger LOGGER = LoggerFactory.getLogger(JDBCStoreProviderBase.class);
108 43020 jjdelcerro
109
    public class CountValue implements CalculatedValue<Long> {
110
111
        private Long value = null;
112
113
        @Override
114
        public void calculate() {
115 44376 jjdelcerro
            try {
116
                JDBCStoreParameters params = getParameters();
117
                CountOperation count = getOperations().createCount(
118
                        getFeatureStore().getDefaultFeatureType(),
119
                        getOperations().createTableReference(params),
120
                        params.getBaseFilter(),
121
                        null
122
                );
123
                this.value = (Long) count.perform();
124
            } catch (DataException ex) {
125
                throw new RuntimeException("Can't calculate count",ex);
126
            }
127 43020 jjdelcerro
        }
128
129
        @Override
130
        public void reset() {
131
            this.value = null;
132
        }
133
134
        @Override
135
        public Long get() {
136
            if( this.value == null ) {
137
                this.calculate();
138
            }
139
            return this.value;
140
        }
141
    }
142
143
    public class EnvelopeValue implements CalculatedValue<Envelope> {
144
145
        private Envelope value = null;
146 43163 jjdelcerro
        private boolean needCalculate = true;
147 43020 jjdelcerro
148
        @Override
149
        public void calculate() {
150 45581 fdiaz
            FeatureStore featureStore;
151
            FeatureType featureType;
152 43020 jjdelcerro
            try {
153 45581 fdiaz
                featureStore = getFeatureStore();
154
                if (featureStore == null) {
155
                    return;
156
                }
157
                featureType = featureStore.getDefaultFeatureType();
158
                if (featureType == null) {
159
                    return;
160
                }
161
            } catch (Exception ex) {
162
                throw new RuntimeException("Can't calculate envelope.", ex);
163
            }
164
            try {
165 43163 jjdelcerro
                value = null;
166 45581 fdiaz
                String columnName = featureType.getDefaultGeometryAttributeName();
167 43163 jjdelcerro
                if( columnName==null ) {
168
                    return;
169
                }
170 47485 fdiaz
                FeatureAttributeDescriptor attr = featureType.getAttributeDescriptor(columnName);
171
                boolean toDataBase = true;
172
                if(attr.isComputed()){
173
                    FeatureAttributeEmulator attrEmulator = attr.getFeatureAttributeEmulator();
174
                    if( !(attrEmulator instanceof FeatureAttributeEmulatorExpression) ) {
175
                        toDataBase = false;
176
                    } else {
177
                        FeatureAttributeEmulatorExpression x = (FeatureAttributeEmulatorExpression) attrEmulator;
178
                        Expression exp = x.getExpression();
179
                        if (exp == null || exp.isEmpty() ) {
180
                            toDataBase = false;
181
                        } else {
182
                            if (!helper.supportExpression(null, exp.getPhrase())) {
183
                                toDataBase = false;
184
                            }
185
                        }
186
                    }
187
                }
188 43163 jjdelcerro
189 47485 fdiaz
                if(toDataBase){
190
                    IProjection crs = getFeatureStore()
191
                            .getDefaultFeatureType()
192
                            .getDefaultSRS();
193
                    JDBCStoreParameters params = getParameters();
194
                    CalculateEnvelopeOfColumnOperation calculateEnvelopeOfColumn =
195
                        getOperations().createCalculateEnvelopeOfColumn(
196
                            getFeatureStore().getDefaultFeatureType(),
197
                            getOperations().createTableReference(params),
198
                            columnName,
199
                            params.getBaseFilter(),
200
                            params.getWorkingArea(),
201
                            crs
202
                        );
203
                    value = (Envelope) calculateEnvelopeOfColumn.perform();
204
                } else {
205
                    FeatureSet fset = getFeatureStore().getFeatureSet();
206
                    Envelope finalEnvelope = GeometryUtils.createEnvelope(Geometry.SUBTYPES.GEOM2D);
207
                    for (Feature feature : fset) {
208
                        Geometry geometry = feature.getGeometry(columnName);
209
                        finalEnvelope.add(geometry);
210
                    }
211
                    value = finalEnvelope;
212
                }
213
214 46303 jjdelcerro
            } catch(Throwable ex) {
215 43020 jjdelcerro
                throw new RuntimeException("Can't calculate envelope.", ex);
216 43163 jjdelcerro
            } finally {
217
               needCalculate = false;
218 43020 jjdelcerro
            }
219
        }
220
221
        @Override
222
        public void reset() {
223
            this.value = null;
224 43163 jjdelcerro
            this.needCalculate = true;
225 43020 jjdelcerro
        }
226
227
        @Override
228 43361 jjdelcerro
        public synchronized Envelope get() {
229 43163 jjdelcerro
            if( needCalculate ) {
230 43020 jjdelcerro
                this.calculate();
231
            }
232
            return this.value;
233
        }
234
    }
235 43163 jjdelcerro
236 43020 jjdelcerro
    public class AllowWriteValue implements CalculatedValue<Boolean> {
237
238
        private Boolean value = null;
239
240
        @Override
241
        public void calculate() {
242
            try {
243
                JDBCStoreParameters params = getParameters();
244
                CanModifyTableOperation canModifyTable =
245
                    getOperations().createCanModifyTableOperation(
246 44058 jjdelcerro
                        getOperations().createTableReference(params)
247 43020 jjdelcerro
                    );
248
                this.value = (boolean) canModifyTable.perform();
249
            } catch(Exception ex) {
250
                throw new RuntimeException("Can't determine if allow write.", ex);
251
            }
252
        }
253
254
        @Override
255
        public void reset() {
256
            this.value = null;
257
        }
258
259
        @Override
260
        public Boolean get() {
261
            if( this.value == null ) {
262
                this.calculate();
263
            }
264
            return this.value;
265
        }
266
    }
267
268
    protected final JDBCHelper helper;
269
270
    protected CalculatedValue<Long> count = null;
271
272
    protected CalculatedValue<Envelope> envelope = null;
273
274
    protected CalculatedValue<Boolean> allowWrite = null;
275
276
    protected AppendOperation appendOperation = null;
277
278 46315 jjdelcerro
    protected Observer transactionObserver;
279
280 44058 jjdelcerro
    @SuppressWarnings({"OverridableMethodCallInConstructor", "CallToThreadStartDuringObjectConstruction"})
281 43020 jjdelcerro
    protected JDBCStoreProviderBase(
282
            JDBCStoreParameters params,
283
            DataStoreProviderServices storeServices,
284
            DynObject metadata,
285
            JDBCHelper helper
286
    ) throws InitializeException {
287
        super(params, storeServices, metadata);
288
        this.helper = helper;
289
        this.initializeFeatureType();
290 43361 jjdelcerro
        try {
291
            if( BooleanUtils.isTrue((Boolean) params.getDynValue("precalculateEnvelope"))  ) {
292
                FeatureType featureType = this.getStoreServices().getDefaultFeatureType();
293
                if( !StringUtils.isEmpty(featureType.getDefaultGeometryAttributeName()) ) {
294 45065 jjdelcerro
                    Thread thread = new Thread(() -> {
295
                        LOGGER.trace("Precalculating envelope of '"+getSourceId()+"'.");
296
                        getEnvelopeValue().get();
297 43361 jjdelcerro
                    }, "PrecalculateEnvelopeOfDBTable");
298
                    thread.start();
299
                    Thread.sleep(1);
300
                }
301
           }
302
        } catch(Exception ex) {
303 44058 jjdelcerro
            LOGGER.warn("Probems precalculating the envelope of table '"+this.getSourceId()+"'.", ex);
304 43361 jjdelcerro
        }
305 46315 jjdelcerro
        this.transactionObserver = new Observer() {
306
            @Override
307
            public void update(Observable o, Object o1) {
308
                if( o1 instanceof BaseNotification && (
309
                        ((BaseNotification)o1).isOfType("ROLLBACK") ||
310
                        ((BaseNotification)o1).isOfType("COMMIT")
311
                        ) ) {
312
                    getCountValue().reset();
313
                    getEnvelopeValue().reset();
314
                }
315
            }
316
        };
317 43020 jjdelcerro
    }
318
319
    @Override
320
    public JDBCStoreParameters getParameters() {
321
        return (JDBCStoreParameters) super.getParameters();
322
    }
323
324
    @Override
325
    public JDBCHelper getHelper() {
326
        return helper;
327
    }
328
329
    public OperationsFactory getOperations() {
330
        return this.getHelper().getOperations();
331
    }
332
333
    @Override
334
    public String getProviderName() {
335
        return this.getHelper().getProviderName();
336
    }
337
338
    @Override
339
    public int getOIDType() {
340
        return DataTypes.UNKNOWN;
341
    }
342
343
    @Override
344
    public Object createNewOID() {
345
        return null;
346
    }
347
348
    @Override
349
    public boolean allowAutomaticValues() {
350
        return this.getHelper().allowAutomaticValues();
351
    }
352
353
    @Override
354
    public boolean allowWrite() {
355
        return this.getAllowWriteValue().get();
356
    }
357
358
    @Override
359
    public Object getDynValue(String name) throws DynFieldNotFoundException {
360
        try {
361
            if (DataStore.METADATA_ENVELOPE.equalsIgnoreCase(name)) {
362
                Envelope env = this.getEnvelope();
363
                if (env != null) {
364
                    return env;
365
                }
366
            } else if (DataStore.METADATA_CRS.equalsIgnoreCase(name)) {
367
                IProjection proj;
368
                proj = this.getFeatureStore().getDefaultFeatureType().getDefaultSRS();
369
                if (proj != null) {
370
                    return proj;
371
                }
372
            }
373
        } catch (DataException e) {
374
            throw new RuntimeException(e);
375
        }
376
        return super.getDynValue(name);
377
    }
378
379
    @Override
380
    public CalculatedValue<Long> getCountValue() {
381
        if( this.count == null ) {
382
            this.count = new CountValue();
383
        }
384
        return this.count;
385
    }
386
387
    @Override
388
    public CalculatedValue<Envelope> getEnvelopeValue() {
389
        if( this.envelope == null ) {
390
            this.envelope = new EnvelopeValue();
391
        }
392
        return this.envelope;
393
    }
394
395
    @Override
396
    public CalculatedValue<Boolean> getAllowWriteValue() {
397
        if( this.allowWrite == null ) {
398
            this.allowWrite = new AllowWriteValue();
399
        }
400
        return this.allowWrite;
401
    }
402
403
    @Override
404
    public long getFeatureCount() throws DataException {
405
        return this.getCountValue().get();
406
    }
407
408
    @Override
409
    public boolean closeResourceRequested(ResourceProvider resource) {
410
        ResulSetControler resulSetControler = this.getHelper().getResulSetControler();
411
        resulSetControler.pack();
412
        return resulSetControler.getOpenCount() == 0;
413
    }
414
415
    @Override
416
    public void close() throws CloseException {
417
        JDBCUtils.closeQuietly(this.getHelper());
418
    }
419
420
    @Override
421
    public void resourceChanged(ResourceProvider resource) {
422
        this.getStoreServices().notifyChange(
423
                DataStoreNotification.RESOURCE_CHANGED,
424
                resource
425
        );
426
    }
427
428
    @Override
429
    public DataServerExplorer getExplorer() throws ReadException {
430
        DataManager manager = DALLocator.getDataManager();
431
        JDBCServerExplorerParameters exParams;
432
        JDBCStoreParameters params = getParameters();
433
        try {
434
            exParams = this.getHelper().createServerExplorerParameters();
435 44185 jjdelcerro
            DynField[] fields = exParams.getDynClass().getDynFields();
436
            for (DynField field : fields) {
437
                try {
438
                    exParams.setDynValue(field.getName(), params.getDynValue(field.getName()));
439
                } catch(Exception ex) {
440
                    // Ignore
441
                }
442
            }
443 43020 jjdelcerro
            exParams.setHost(params.getHost());
444
            exParams.setPort(params.getPort());
445
            exParams.setDBName(params.getDBName());
446
            exParams.setUser(params.getUser());
447
            exParams.setPassword(params.getPassword());
448
            exParams.setUrl(params.getUrl());
449
            exParams.setCatalog(params.getCatalog());
450
            exParams.setSchema(params.getSchema());
451
            exParams.setJDBCDriverClassName(params.getJDBCDriverClassName());
452 47606 fdiaz
453
            DataServerExplorer explorer = manager.openServerExplorer(exParams.getExplorerName(), exParams);
454
            DataTransaction.add(this.helper.getTransaction(), explorer, false);
455 43020 jjdelcerro
456 47606 fdiaz
            return explorer;
457 43020 jjdelcerro
        } catch (Exception e) {
458
            throw new ReadException(this.getProviderName(), e);
459
        }
460
    }
461
462
    @Override
463
    protected void doDispose() throws BaseException {
464 46315 jjdelcerro
        if( this.helper.getTransaction()!=null ) {
465
            this.helper.getTransaction().deleteObserver(transactionObserver);
466
        }
467 43020 jjdelcerro
        this.close();
468
        this.getHelper().dispose();
469
        super.doDispose();
470
    }
471
472
    @Override
473
    public String getSourceId() {
474 43361 jjdelcerro
        try {
475
            return this.getHelper().getSourceId(this.getParameters());
476
        } catch(Exception ex) {
477
            return "unknow";
478
        }
479 43020 jjdelcerro
    }
480
481
    @Override
482
    public String getName() {
483 43397 jjdelcerro
        return this.getParameters().getTable();
484 43020 jjdelcerro
    }
485
486
    @Override
487
    public String getFullName() {
488
        return this.getHelper().getSourceId(this.getParameters());
489
    }
490
491 43409 jjdelcerro
    private static class DummyResource extends AbstractResource {
492
493
        private final String name;
494
495
        DummyResource(String name) throws InitializeException {
496
            super((ResourceParameters)null);
497
            this.name = name;
498
        }
499
500
        @Override
501
        public String getName() throws AccessResourceException {
502
            return MessageFormat.format("DummyResource({0})",
503
                                new Object[] { this.name });
504
        }
505
506
        @Override
507
        public Object get() throws AccessResourceException {
508
            return null;
509
        }
510
511
        @Override
512
        public boolean isThis(ResourceParameters parameters) throws ResourceException {
513
            return true;
514
        }
515
516
    }
517
518 43020 jjdelcerro
    @Override
519
    public ResourceProvider getResource() {
520 43409 jjdelcerro
        ResourceProvider r = getHelper().getResource();
521
        if( r == null ) {
522
            try {
523
                r = new DummyResource(this.getName());
524
            } catch (InitializeException ex) {
525 44058 jjdelcerro
                LOGGER.warn("Can't create DummyResource",ex);
526 43409 jjdelcerro
                // Do nothing
527
            }
528
        }
529
        return r;
530 43020 jjdelcerro
    }
531
532
    @Override
533
    public void open() throws OpenException {
534
535
    }
536
537
    @Override
538
    public FeatureSetProvider createSet(
539
            FeatureQuery query,
540
            FeatureType featureType
541
        ) throws DataException {
542
543
        FeatureSetProvider set = new JDBCSetProvider(
544
                this,
545
                this.getHelper(),
546
                query,
547
                featureType
548
        );
549
550
        return set;
551
    }
552
553
    protected void initializeFeatureType() {
554
        EditableFeatureType type = this.getStoreServices().createFeatureType(getName());
555
        JDBCStoreParameters params = this.getParameters();
556
        List<String> primaryKeys = null;
557
        if( params.getPkFields() != null ) {
558
            primaryKeys = Arrays.asList(params.getPkFields());
559
        }
560
        FetchFeatureTypeOperation fetchFeatureType =
561
             this.getOperations().createFetchFeatureType(
562
                type,
563 44058 jjdelcerro
                this.getOperations().createTableReference(params),
564 43020 jjdelcerro
                primaryKeys,
565
                params.getDefaultGeometryField(),
566 45626 fdiaz
                params.getCRS(),
567
                params.getGeometryType(),
568
                params.getGeometrySubtype()
569 43020 jjdelcerro
            );
570
        fetchFeatureType.perform();
571
572 45008 omartinez
        if (!StringUtils.isBlank(params.getDefaultGeometryField())) {
573
            if (!params.getDefaultGeometryField().equalsIgnoreCase(type.getDefaultGeometryAttributeName())) {
574
                if (type.getAttributeDescriptor(params.getDefaultGeometryField()) != null) {
575
                    type.setDefaultGeometryAttributeName(params.getDefaultGeometryField());
576
                } else {
577
                    type.setDefaultGeometryAttributeName(null);
578
                }
579
                if (type.getDefaultGeometryAttribute() != null) {
580
                    EditableFeatureAttributeDescriptor attr = (EditableFeatureAttributeDescriptor) type.getDefaultGeometryAttribute();
581
                    attr.setGeometryType(Geometry.TYPES.GEOMETRY, Geometry.SUBTYPES.GEOM2D);
582
                }
583
            } else {
584
                type.setDefaultGeometryAttributeName(null);
585 43420 jjdelcerro
            }
586
        }
587 45008 omartinez
588 43020 jjdelcerro
        FeatureType defaultType = type.getNotEditableCopy();
589 45152 fdiaz
        this.getHelper().setProviderFeatureType(defaultType);
590 43020 jjdelcerro
        List<FeatureType> types = Collections.singletonList(defaultType);
591
        this.getStoreServices().setFeatureTypes(types, defaultType);
592
    }
593 45614 fdiaz
594 43020 jjdelcerro
    @Override
595
    protected FeatureProvider internalGetFeatureProviderByReference(
596
            FeatureReferenceProviderServices reference,
597
            FeatureType featureType
598
        ) throws DataException {
599
        JDBCStoreParameters params = this.getParameters();
600
        FetchFeatureProviderByReferenceOperation fetchFeatureProviderByReference =
601
            this.getOperations().createFetchFeatureProviderByReference(
602
                reference,
603
                featureType,
604 44058 jjdelcerro
                this.getOperations().createTableReference(params)
605 43020 jjdelcerro
            );
606
        FeatureProvider feature = (FeatureProvider) fetchFeatureProviderByReference.perform();
607
        return feature;
608
    }
609
610
    @Override
611
    public Envelope getEnvelope() throws DataException {
612
        return this.getEnvelopeValue().get();
613
    }
614
615
    @Override
616
    public void performChanges(Iterator deleteds, Iterator inserteds,
617
                    Iterator updateds, Iterator featureTypesChanged)
618
                    throws DataException {
619
620
        FeatureType type = this.getFeatureStore().getDefaultFeatureType();
621
        JDBCStoreParameters params = this.getParameters();
622
        PerformChangesOperation performChanges = this.getOperations().createPerformChanges(
623 44058 jjdelcerro
                this.getOperations().createTableReference(params),
624 43020 jjdelcerro
                type,
625
                deleteds,
626
                inserteds,
627
                updateds,
628 46724 fdiaz
                featureTypesChanged,
629
                this.getStoreServices()
630 43020 jjdelcerro
        );
631
        performChanges.perform();
632
        if( performChanges.isTypeChanged() ) {
633
            // Get rules before initializing feature type
634
            FeatureRules saved_rules = getFeatureStore().getDefaultFeatureType().getRules();
635
636
             // This initialization loses the feature type rules
637
            this.initializeFeatureType();
638
639
            // Get new feature type, clear rules and add the ones saved previously
640
            FeatureType featureType = getFeatureStore().getDefaultFeatureType();
641
            FeatureRules rules = featureType.getRules();
642
            rules.clear();
643
            for (FeatureRule rule : saved_rules) {
644
                rules.add(rule);
645
            }
646
        }
647
        this.getCountValue().reset();
648
        this.getEnvelopeValue().reset();
649
    }
650
651
    @Override
652
    public boolean supportsAppendMode() {
653
        return true;
654
    }
655
656 46032 jjdelcerro
    protected AppendOperation createAppendOperation() throws DataException {
657
        FeatureType type = this.getFeatureStore().getDefaultFeatureType();
658
        JDBCStoreParameters params = this.getParameters();
659
        AppendOperation theAppendOperation = this.getOperations().createAppend(
660 44058 jjdelcerro
                this.getOperations().createTableReference(params),
661 43020 jjdelcerro
                type
662 46032 jjdelcerro
        );
663
        return theAppendOperation;
664 43020 jjdelcerro
    }
665
666
    @Override
667
    public void endAppend() throws DataException {
668 46032 jjdelcerro
        this.appendOperation.end();
669 46315 jjdelcerro
        this.getCountValue().reset();
670
        this.getEnvelopeValue().reset();
671 43020 jjdelcerro
    }
672
673
    @Override
674 43408 jjdelcerro
    public void abortAppend() throws DataException {
675 46032 jjdelcerro
        this.appendOperation.abort();
676 43408 jjdelcerro
    }
677
678
    @Override
679 43020 jjdelcerro
    public void beginAppend() throws DataException {
680 47779 fdiaz
        this.beginAppend(FeatureStore.SUBMODE_NONE);
681
    }
682
683
    @Override
684
    public void beginAppend(int submode) throws DataException {
685 46032 jjdelcerro
        if( this.appendOperation == null ) {
686
            this.appendOperation = createAppendOperation();
687
        }
688 47779 fdiaz
        this.appendOperation.begin(submode);
689 43020 jjdelcerro
    }
690 47779 fdiaz
691 43020 jjdelcerro
    @Override
692
    public void append(final FeatureProvider featureProvider) throws DataException {
693 46032 jjdelcerro
        this.appendOperation.append(featureProvider);
694 43020 jjdelcerro
    }
695
696
    @Override
697
    public boolean canWriteGeometry(int geometryType, int geometrySubtype)
698
            throws DataException {
699
        return this.getHelper().canWriteGeometry(geometryType,geometrySubtype);
700
    }
701 45425 jjdelcerro
702
    @Override
703
    public boolean supportsPassThroughMode() {
704
        return true;
705
    }
706
707
    @Override
708
    public void passThroughInsert(FeatureProvider featureProvider) throws DataException {
709
        FeatureType type = this.getFeatureStore().getDefaultFeatureType();
710
        JDBCStoreParameters params = this.getParameters();
711
        PerformChangesOperation performChanges = this.getOperations().createPerformChanges(
712
                this.getOperations().createTableReference(params),
713
                type,
714
                Collections.emptyIterator(),
715
                Collections.singletonList(featureProvider).iterator(),
716
                Collections.emptyIterator(),
717 46724 fdiaz
                Collections.emptyIterator(),
718
                this.getStoreServices()
719 45425 jjdelcerro
        );
720
        performChanges.perform();
721 46315 jjdelcerro
        this.getCountValue().reset();
722
        this.getEnvelopeValue().reset();
723 45425 jjdelcerro
    }
724
725
    @Override
726
    public void passThroughUpdate(FeatureProvider featureProvider) throws DataException {
727
        FeatureType type = this.getFeatureStore().getDefaultFeatureType();
728
        JDBCStoreParameters params = this.getParameters();
729
        PerformChangesOperation performChanges = this.getOperations().createPerformChanges(
730
                this.getOperations().createTableReference(params),
731
                type,
732
                Collections.emptyIterator(),
733
                Collections.emptyIterator(),
734
                Collections.singletonList(featureProvider).iterator(),
735 46724 fdiaz
                Collections.emptyIterator(),
736
                this.getStoreServices()
737 45425 jjdelcerro
        );
738
        performChanges.perform();
739 46315 jjdelcerro
//        this.getCountValue().reset();
740
        this.getEnvelopeValue().reset();
741 45425 jjdelcerro
    }
742
743 45473 fdiaz
    @Override
744 45425 jjdelcerro
    public void passThroughUpdate(Object[] parameters, Expression filter){
745 45473 fdiaz
        JDBCStoreParameters params = this.getParameters();
746
        UpdatePassThroughOperation operation = this.getOperations().createUpdatePassThroughOperation(
747
                this.getOperations().createTableReference(params),
748
                parameters,
749
                filter
750
        );
751
        operation.perform();
752 46315 jjdelcerro
//        this.getCountValue().reset();
753
        this.getEnvelopeValue().reset();
754 45425 jjdelcerro
    }
755
756
    @Override
757
    public void passThroughDelete(FeatureReferenceProviderServices featureReference) throws DataException {
758
        FeatureType type = this.getFeatureStore().getDefaultFeatureType();
759
        JDBCStoreParameters params = this.getParameters();
760
        PerformChangesOperation performChanges = this.getOperations().createPerformChanges(
761
                this.getOperations().createTableReference(params),
762
                type,
763
                Collections.singletonList(featureReference).iterator(),
764
                Collections.emptyIterator(),
765
                Collections.emptyIterator(),
766 46724 fdiaz
                Collections.emptyIterator(),
767
                this.getStoreServices()
768 45425 jjdelcerro
        );
769
        performChanges.perform();
770 46315 jjdelcerro
        this.getCountValue().reset();
771
        this.getEnvelopeValue().reset();
772 45425 jjdelcerro
    }
773
774 46542 fdiaz
    @Override
775 45425 jjdelcerro
    public void passThroughDelete(Expression expression) throws DataException {
776 45473 fdiaz
        JDBCStoreParameters params = this.getParameters();
777
        DeletePassThroughOperation operation = this.getOperations().createDeletePassThroughOperation(
778
                this.getOperations().createTableReference(params),
779
                expression
780
        );
781
        operation.perform();
782 46315 jjdelcerro
        this.getCountValue().reset();
783
        this.getEnvelopeValue().reset();
784 45425 jjdelcerro
    }
785 45650 jjdelcerro
786
    @Override
787
    public void setTransaction(DataTransactionServices transaction) {
788 46315 jjdelcerro
        if( this.helper.getTransaction()!=null ) {
789
            this.helper.getTransaction().deleteObserver(transactionObserver);
790
        }
791 45650 jjdelcerro
        this.helper.setTransaction(transaction);
792 46315 jjdelcerro
        if( transaction!=null ) {
793
            transaction.addObserver(transactionObserver);
794
        }
795 45650 jjdelcerro
    }
796
797 45717 fdiaz
    @Override
798
    public String toString() {
799
        try {
800 47198 jjdelcerro
            ToStringBuilder builder = new ToStringBuilder(this);
801
            builder.append("hash", String.format("%x", this.hashCode()));
802
            builder.append("helper", this.helper, true);
803
            return builder.toString();
804 45717 fdiaz
        } catch (Exception e) {
805
            return super.toString();
806
        }
807
    }
808 46032 jjdelcerro
809
    @Override
810
    public void refresh() throws OpenException {
811 46303 jjdelcerro
        // Force to recalculare count, envelope and allowWrite
812
        this.count = null;
813
        this.envelope = null;
814
        this.allowWrite = null;
815 46032 jjdelcerro
//
816
//        if( this.helper.getResulSetControler().getOpenCount()>0 ) {
817
//            // Has ResultSetEntry open. Oh!!!!
818
//            this.helper.getResulSetControler().closeAll();
819
//        }
820
//        if( this.appendOperation!=null ) {
821
//            // Has and append operation in progress, Oh!!
822
//            this.appendOperation.abort();
823
//            this.appendOperation = null;
824
//        }
825
        super.refresh();
826
    }
827 47779 fdiaz
828 43020 jjdelcerro
}