Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.compat.cdc / org.gvsig.fmap.dal / org.gvsig.fmap.dal.spi / src / main / java / org / gvsig / fmap / dal / feature / spi / AbstractFeatureStoreProvider.java @ 47436

History | View | Annotate | Download (19 KB)

1
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright (C) 2007-2013 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

    
25
package org.gvsig.fmap.dal.feature.spi;
26

    
27
import java.io.BufferedOutputStream;
28
import java.io.File;
29
import java.io.FileOutputStream;
30
import java.io.OutputStream;
31
import java.nio.charset.StandardCharsets;
32
import java.util.Collection;
33
import java.util.Iterator;
34
import org.apache.commons.io.FileUtils;
35
import org.apache.commons.io.FilenameUtils;
36
import org.apache.commons.io.IOUtils;
37
import org.apache.commons.lang3.builder.ToStringBuilder;
38
import org.cresques.cts.ICRSFactory;
39
import org.cresques.cts.IProjection;
40
import org.gvsig.expressionevaluator.Expression;
41
import org.gvsig.expressionevaluator.ExpressionBuilder;
42
import org.gvsig.expressionevaluator.ExpressionEvaluatorLocator;
43
import org.gvsig.fmap.dal.DALLocator;
44
import org.gvsig.fmap.dal.DataServerExplorer;
45
import org.gvsig.fmap.dal.DataStore;
46
import org.gvsig.fmap.dal.DataStoreParameters;
47
import org.gvsig.fmap.dal.StoresRepository;
48
import org.gvsig.fmap.dal.exception.CloseException;
49
import org.gvsig.fmap.dal.exception.DataException;
50
import org.gvsig.fmap.dal.exception.InitializeException;
51
import org.gvsig.fmap.dal.exception.OpenException;
52
import org.gvsig.fmap.dal.exception.ReadException;
53
import org.gvsig.fmap.dal.exception.ValidateDataParametersException;
54
import org.gvsig.fmap.dal.feature.FeatureLocks;
55
import org.gvsig.fmap.dal.feature.FeatureQuery;
56
import org.gvsig.fmap.dal.feature.FeatureReference;
57
import org.gvsig.fmap.dal.feature.FeatureSelection;
58
import org.gvsig.fmap.dal.feature.FeatureStore;
59
import org.gvsig.fmap.dal.feature.FeatureType;
60
import org.gvsig.fmap.dal.resource.ResourceAction;
61
import org.gvsig.fmap.dal.resource.ResourceManager;
62
import org.gvsig.fmap.dal.resource.spi.ResourceManagerProviderServices;
63
import org.gvsig.fmap.dal.resource.spi.ResourceProvider;
64
import org.gvsig.fmap.dal.spi.AbstractDataStoreProvider;
65
import org.gvsig.fmap.dal.spi.DataStoreProviderServices;
66
import org.gvsig.fmap.dal.spi.DataTransactionServices;
67
import org.gvsig.fmap.geom.primitive.Envelope;
68
import org.gvsig.timesupport.Interval;
69
import org.gvsig.tools.dynobject.DelegatedDynObject;
70
import org.gvsig.tools.dynobject.DynClass;
71
import org.gvsig.tools.dynobject.DynObject;
72
import org.gvsig.tools.dynobject.DynObject_v2;
73
import org.gvsig.tools.dynobject.exception.DynFieldNotFoundException;
74
import org.gvsig.tools.dynobject.exception.DynMethodException;
75
import org.gvsig.tools.exception.BaseException;
76
import org.gvsig.tools.resourcesstorage.ResourcesStorage;
77
import org.gvsig.tools.util.UnmodifiableBasicMap;
78
import org.slf4j.Logger;
79
import org.slf4j.LoggerFactory;
80

    
81
/**
82
 * Abstract implementation of {@link FeatureStoreProvider}
83
 *
84
 */
85
public abstract class AbstractFeatureStoreProvider extends AbstractDataStoreProvider
86
                implements FeatureStoreProvider_v2 {
87

    
88
        protected FeatureStoreProviderServices store;
89
        private DelegatedDynObject metadata;
90
        private DataStoreParameters parameters;
91

    
92
    private static final Logger logger = LoggerFactory.getLogger(AbstractFeatureStoreProvider.class);
93

    
94

    
95
        /**
96
         * Default Constructor.
97
         *
98
         * @param params
99
         * @param storeServices
100
         * @param metadata
101
         */
102
        protected AbstractFeatureStoreProvider(DataStoreParameters params,
103
                        DataStoreProviderServices storeServices, DynObject metadata) {
104
                this.store = (FeatureStoreProviderServices) storeServices;
105
                this.metadata = (DelegatedDynObject) metadata;
106
                this.parameters = params;
107
        }
108

    
109
        /**
110
         * Constructor when cannot create metada in constrution time. <br>
111
         * <br>
112
         * <strong>Note: </strong> Don't use it if not is necesary. Set metada
113
         * <strong>as soon as posible</strong> by
114
         * {@link AbstractFeatureStoreProvider#setMetadata(DynObject)}
115
         *
116
         * @param params
117
         * @param storeServices
118
         */
119
        protected AbstractFeatureStoreProvider(DataStoreParameters params,
120
                        DataStoreProviderServices storeServices) {
121
                this.store = (FeatureStoreProviderServices) storeServices;
122
                this.metadata = null;
123
                this.parameters = params;
124
        }
125

    
126
        public final FeatureProvider getFeatureProviderByReference(
127
                        final FeatureReferenceProviderServices reference)
128
                        throws DataException {
129
                this.open();
130
                FeatureProvider featureProvider = (FeatureProvider) getResource()
131
                                .execute(new ResourceAction() {
132
                                        public Object run() throws Exception {
133
                                                return internalGetFeatureProviderByReference(reference);
134
                                        }
135
                                        public String toString() {
136
                                            return "getFeatureByReference";
137
                                        }
138

    
139
                                });
140

    
141
                if (featureProvider == null) {
142
                        throw new FeatureProviderNotFoundException(reference);
143
                }
144

    
145
                return featureProvider;
146
        }
147

    
148
        public final FeatureProvider getFeatureProviderByReference(
149
                        final FeatureReferenceProviderServices reference,
150
                        final FeatureType featureType) throws DataException {
151
                this.open();
152
                FeatureProvider featureProvider = (FeatureProvider) getResource()
153
                                .execute(new ResourceAction() {
154
                        public Object run() throws Exception {
155
                                return internalGetFeatureProviderByReference(reference,
156
                                                featureType);
157
                        }
158
                });
159

    
160
                if (featureProvider == null) {
161
                        throw new FeatureProviderNotFoundException(reference);
162
                }
163

    
164
                return featureProvider;
165
        }
166

    
167
        /**
168
         * Returns a {@link FeatureProvider} by reference, using the default
169
         * {@link FeatureType}. This method may be rewritten by the child classes as
170
         * an implementation of the
171
         * {@link #getFeatureProviderByReference(FeatureReferenceProviderServices)}
172
         * method.
173
         *
174
         * @param reference
175
         *            the reference to the {@link FeatureProvider}
176
         * @return the {@link FeatureProvider} being referenced
177
         * @throws DataException
178
         *             if there is an error loading the {@link FeatureProvider}
179
         */
180
        protected FeatureProvider internalGetFeatureProviderByReference(
181
                        FeatureReferenceProviderServices reference) throws DataException {
182
                return internalGetFeatureProviderByReference(reference,
183
                                getStoreServices().getDefaultFeatureType());
184
        }
185

    
186
        /**
187
         * Set metada container if this not set at construction time and only in one
188
         * time. In other case an Exception will be throw
189
         *
190
         * @param metadata
191
         */
192
        protected void setMetadata(DynObject metadata) {
193
                if (this.metadata != null) {
194
                        // FIXME Exception
195
                        throw new IllegalStateException();
196
                }
197
                this.metadata = (DelegatedDynObject) metadata;
198
        }
199

    
200
        /**
201
         * @return the parameters
202
         */
203
        public DataStoreParameters getParameters() {
204
                return parameters;
205
        }
206

    
207
        /**
208
         * Create or get a resource of <code>type</code> for <code>params</code> in
209
         * {@link ResourceManager}
210
         *
211
         * @param type
212
         * @param params
213
         * @return
214
         * @throws InitializeException
215
         */
216
        protected ResourceProvider createResource(String type, Object[] params)
217
                        throws InitializeException {
218
                ResourceManagerProviderServices manager = (ResourceManagerProviderServices) DALLocator
219
                                .getResourceManager();
220
                ResourceProvider resource = manager.createAddResource(type, params);
221
                return resource;
222
        }
223

    
224
        @Override
225
        public FeatureStoreProviderServices getStoreServices() {
226
                return this.store;
227
        }
228

    
229
        @Override
230
        public FeatureStore getFeatureStore() {
231
            FeatureStoreProviderServices services = this.getStoreServices();
232
            if(services == null){
233
                    return null;
234
            }
235
            return services.getFeatureStore();
236
        }
237

    
238
        @Override
239
        public boolean allowWrite() {
240
                return false;
241
        }
242

    
243
        /**
244
         * unsupported by default, override this otherwise
245
         *
246
         * @see org.gvsig.fmap.dal.feature.spi.FeatureStoreProvider#performChanges(Iterator,
247
         *      Iterator, Iterator, Iterator)
248
         */
249

    
250
        public void performChanges(Iterator deleteds, Iterator inserteds,
251
                        Iterator updateds, Iterator featureTypesChanged)
252
                        throws DataException {
253
                // FIXME exception
254
                throw new UnsupportedOperationException();
255

    
256
        }
257

    
258
        /**
259
         * unsupported by default, override this otherwise
260
         *
261
         * @see org.gvsig.fmap.dal.feature.spi.FeatureStoreProvider#isLocksSupported()
262
         */
263
        public boolean isLocksSupported() {
264
                return false;
265
        }
266

    
267
        /**
268
         * Default Factory of {@link FeatureProvider}. Create a new default
269
         * {@link FeatureProvider} instance.<br>
270
         *
271
         * Override this if you need an special implemtation of
272
         * {@link FeatureProvider}.
273
         *
274
         * @return
275
         * @throws DataException
276
         *
277
         * @see {@link org.gvsig.fmap.dal.feature.spi.FeatureStoreProvider#createFeatureProvider(FeatureType)}
278
         */
279

    
280
        public FeatureProvider createFeatureProvider(FeatureType type)
281
                        throws DataException {
282
            FeatureStoreProviderServices services = this.getStoreServices();
283
            return services.createDefaultFeatureProvider(type);
284
        }
285

    
286
        /**
287
         * unsupported by default (return <code>null</code>), override this
288
         * otherwise
289
         *
290
         * @see org.gvsig.fmap.dal.feature.spi.FeatureStoreProvider#createFeatureLocks()
291
         */
292
        public FeatureLocks createFeatureLocks() throws DataException {
293
                return null;
294
        }
295

    
296
        /**
297
         * Default Factory of {@link FeatureSelection}. Create a new default
298
         * {@link FeatureSelection} instance.<br>
299
         *
300
         * Override this if you need an special implemtation of
301
         * {@link FeatureSelection}.
302
         *
303
         * @return
304
         * @throws DataException
305
         *
306
         * @see org.gvsig.fmap.dal.feature.spi.FeatureStoreProvider#createFeatureSelection()
307
         */
308
        @Override
309
        public FeatureSelection createFeatureSelection() throws DataException {
310
            FeatureStoreProviderServices services = this.getStoreServices();
311
            return services.createDefaultFeatureSelection();
312
        }
313

    
314
        /**
315
         * do nothing by default, override this otherwise
316
         *
317
         * @see org.gvsig.fmap.dal.feature.spi.FeatureStoreProvider#refresh()
318
         */
319
        public void refresh() throws OpenException {
320
                // Do nothing by default
321
        }
322

    
323
        /**
324
         * do nothing by default, override this otherwise
325
         *
326
         * @see org.gvsig.fmap.dal.feature.spi.FeatureStoreProvider#close()
327
         */
328
        @Override
329
        public void close() throws CloseException {
330
                // Do nothing by default
331
        }
332

    
333
        @Override
334
        protected void doDispose() throws BaseException {
335
                this.metadata = null;
336
                this.store = null;
337
        }
338

    
339
        /**
340
         * unsupported geometry by default (return <code>null</code>), override this
341
         * otherwise
342
         *
343
         * @see org.gvsig.fmap.dal.feature.spi.FeatureStoreProvider#getEnvelope()
344
         */
345
        public Envelope getEnvelope() throws DataException {
346
                return null;
347
        }
348

    
349
        /**
350
         * unsupported geometry write by default (return <code>false</code>),
351
         * override this otherwise
352
         *
353
         * @see org.gvsig.fmap.dal.feature.spi.FeatureStoreProvider#canWriteGeometry(int,
354
         *      int)
355
         */
356
        public boolean canWriteGeometry(int geometryType, int geometrySubType)
357
                        throws DataException {
358
                return false;
359
        }
360

    
361
        // --- Metadata methods ---
362

    
363
        public void delegate(DynObject dynObject) {
364
                if (this.metadata == null) {
365
                        return;
366
                }
367
                this.metadata.delegate(dynObject);
368
        }
369

    
370
        public DynClass getDynClass() {
371
                if (this.metadata == null) {
372
                        return null;
373
                }
374
                return this.metadata.getDynClass();
375
        }
376

    
377
        public Object getDynValue(String name) throws DynFieldNotFoundException {
378
                if (this.metadata == null) {
379
                        return null;
380
                }
381
                // TODO this.open??
382
                return this.metadata.getDynValue(name);
383
        }
384

    
385
        public boolean hasDynValue(String name) {
386
                if (this.metadata == null) {
387
                        return false;
388
                }
389
                // TODO this.open??
390
                return this.metadata.hasDynValue(name);
391
        }
392

    
393
    @Override
394
    public boolean hasDynMethod(String name) {
395
        if( metadata instanceof DynObject_v2 ) {
396
            return ((DynObject_v2)this.metadata).hasDynMethod(name);
397
        }
398
        return false;
399
    }
400

    
401
        public void implement(DynClass dynClass) {
402
                if (this.metadata == null) {
403
                        return;
404
                }
405
                this.metadata.implement(dynClass);
406

    
407
        }
408

    
409
        public Object invokeDynMethod(int code, Object[] args)
410
                        throws DynMethodException {
411
                if (this.metadata == null) {
412
                        return null;
413
                }
414
                // TODO this.open??
415
                return this.metadata.invokeDynMethod(this, code, args);
416
        }
417

    
418
        public Object invokeDynMethod(String name, Object[] args)
419
                        throws DynMethodException {
420
                if (this.metadata == null) {
421
                        return null;
422
                }
423
                // TODO this.open??
424
                return this.metadata.invokeDynMethod(this, name, args);
425
        }
426

    
427
        public void setDynValue(String name, Object value)
428
                        throws DynFieldNotFoundException {
429
                if (this.metadata == null) {
430
                        return;
431
                }
432
                // TODO this.open??
433
                this.metadata.setDynValue(name, value);
434
        }
435

    
436
        // --- end Metadata methods ---
437

    
438
        /**
439
         * unsupported by default, override this otherwise
440
         *
441
         * @see org.gvsig.fmap.dal.feature.spi.FeatureStoreProvider#allowAutomaticValues()
442
         */
443
        public boolean allowAutomaticValues() {
444
                return false;
445

    
446
        }
447

    
448
        /**
449
         * unsupported by default, override this otherwise
450
         *
451
         * @see org.gvsig.fmap.dal.feature.spi.FeatureStoreProvider#append(org.gvsig.
452
         *      fmap.dal.feature.spi.FeatureProvider)
453
         */
454
        public void append(FeatureProvider featureProvider) throws DataException {
455
                // FIXME exception
456
                throw new UnsupportedOperationException();
457
        }
458

    
459
        /**
460
         * unsupported by default, override this otherwise
461
         *
462
         * @see org.gvsig.fmap.dal.feature.spi.FeatureStoreProvider#beginAppend()
463
         */
464
        public void beginAppend() throws DataException {
465
                // FIXME exception
466
                throw new UnsupportedOperationException();
467
        }
468

    
469
        /**
470
         * unsupported by default, override this otherwise
471
         *
472
         * @see org.gvsig.fmap.dal.feature.spi.FeatureStoreProvider#endAppend()
473
         */
474
        public void endAppend() throws DataException {
475
                // FIXME exception
476
                throw new UnsupportedOperationException();
477
        }
478

    
479
        public void abortAppend() throws DataException {
480
                // FIXME exception
481
                throw new UnsupportedOperationException();
482
        }
483

    
484
        @Override
485
        public boolean supportsAppendMode() {
486
                return false;
487
        }
488

    
489
        @Override
490
        public UnmodifiableBasicMap<String,DataStore> getChildren() {
491
                return UnmodifiableBasicMap.EMPTY_UNMODIFIABLEBASICMAP;
492
        }
493

    
494
        @Override
495
        public StoresRepository getStoresRepository() {
496
            return null;
497
        }
498
        
499
        @Override
500
        public ResourcesStorage getResourcesStorage() {
501
            return null;
502
        }
503

    
504
        /**
505
         * unsupported by default (return null), override this otherwise
506
         *
507
         * @throws org.gvsig.fmap.dal.exception.ReadException
508
         * @throws org.gvsig.fmap.dal.exception.ValidateDataParametersException
509
         * @see org.gvsig.fmap.dal.spi.DataStoreProvider#getExplorer()
510
         */
511
        @Override
512
        public DataServerExplorer getExplorer() throws ReadException,
513
                        ValidateDataParametersException {
514
                return null;
515
        }
516

    
517
        public void clear() {
518
                if (metadata != null) {
519
                        metadata.clear();
520
                }
521
        }
522

    
523
        /**
524
         * Returns a {@link FeatureProvider} by reference, using the provided
525
         * {@link FeatureType}. This is the child classes implementation of the
526
         * {@link #getFeatureProviderByReference(FeatureReferenceProviderServices)}
527
         * method.
528
         *
529
         * @param reference
530
         *            the reference to the {@link FeatureProvider}
531
         * @param featureType
532
         *            the type of feature to load
533
         * @return the {@link FeatureProvider} being referenced
534
         * @throws DataException
535
         *             if there is an error loading the {@link FeatureProvider}
536
         */
537
        protected abstract FeatureProvider internalGetFeatureProviderByReference(
538
                        FeatureReferenceProviderServices reference, FeatureType featureType)
539
                        throws DataException;
540

    
541
        public static class FeatureProviderNotFoundException extends DataException {
542

    
543
                private static final long serialVersionUID = 5161749797695723151L;
544

    
545
                public FeatureProviderNotFoundException(FeatureReference reference) {
546
                        super("Cannot retreive FeatureProvider for reference %(reference)",
547
                                        "_FeatureProviderNotFoundException", serialVersionUID);
548
                        setValue("reference", reference.toString());
549
                }
550
        }
551

    
552
        public boolean isKnownEnvelope(){
553
            return true;
554
        }
555

    
556
    public boolean hasRetrievedFeaturesLimit(){
557
        return false;
558
    }
559

    
560
    public int getRetrievedFeaturesLimit(){
561
        return -1;
562
    }
563

    
564
    public Interval getInterval() {
565
        return null;
566
    }
567

    
568
    public Collection getTimes() {
569
        // TODO Auto-generated method stub
570
        return null;
571
    }
572

    
573
    public Collection getTimes(Interval interval) {
574
        // TODO Auto-generated method stub
575
        return null;
576
    }
577

    
578
    @Override
579
    public ExpressionBuilder createExpression() {
580
        ExpressionBuilder builder = ExpressionEvaluatorLocator.getManager().createExpressionBuilder();
581
        return builder;
582
    }
583

    
584
    protected void savePrjFile(File dataFile, IProjection proj){
585
        File file = new File(FilenameUtils.removeExtension(dataFile.getAbsolutePath())+".prj");
586
        try {
587
            String export = proj.export(ICRSFactory.FORMAT_WKT_ESRI);
588
            if(export!=null){
589
                OutputStream os = null;
590
                try {
591
                    os = new BufferedOutputStream(FileUtils.openOutputStream(file));
592
                    IOUtils.write(export, os, StandardCharsets.UTF_8);
593
                } finally {
594
                    IOUtils.closeQuietly(os);
595
                }
596
            }
597
        } catch (Exception e) {
598
            logger.info("Can't write prj file '" + file.getAbsolutePath() + "'.");
599
        }
600
    }
601

    
602
    @Override
603
    public boolean isTemporary() {
604
        return false;
605
    }
606

    
607
    @Override
608
    public void fixFeatureTypeFromParameters() {
609
        
610
    }
611

    
612
    @Override
613
    public boolean supportsPassThroughMode() {
614
        return false;
615
    }
616

    
617
    @Override
618
    public void passThroughInsert(FeatureProvider featureProvider) throws DataException {
619
        throw new UnsupportedOperationException();
620
    }
621

    
622
    @Override
623
    public void passThroughUpdate(FeatureProvider featureProvider) throws DataException {
624
        throw new UnsupportedOperationException();
625
    }
626
    
627
    @Override
628
    public void passThroughDelete(FeatureReferenceProviderServices featureReference) throws DataException {
629
        throw new UnsupportedOperationException();
630
    }
631
    
632
    @Override
633
    public void passThroughDelete(Expression filter) throws DataException {
634
        throw new UnsupportedOperationException();
635
    }
636
    
637
    @Override
638
    public void passThroughUpdate(Object[] parameters, Expression filter){
639
        throw new UnsupportedOperationException();
640
    }
641

    
642
    @Override
643
    public String toString() {
644
        try {
645
            ToStringBuilder builder = new ToStringBuilder(this);
646
            builder.append("parameters", this.parameters, true);
647
            return builder.toString();
648
        } catch (Exception e) {
649
            return super.toString();
650
        }
651
    }
652

    
653
    @Override
654
    public FeatureSetProvider createSet(FeatureQuery query, FeatureType providerFeatureType, FeatureType storeFeatureType) throws DataException {
655
        return this.createSet(query, storeFeatureType);
656
    }
657
    
658
    
659
}