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

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

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

    
86
        protected FeatureStoreProviderServices store;
87
        private DelegatedDynObject metadata;
88
        private DataStoreParameters parameters;
89

    
90
    private static final Logger logger = LoggerFactory.getLogger(AbstractFeatureStoreProvider.class);
91

    
92

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

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

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

    
137
                                });
138

    
139
                if (featureProvider == null) {
140
                        throw new FeatureProviderNotFoundException(reference);
141
                }
142

    
143
                return featureProvider;
144
        }
145

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

    
158
                if (featureProvider == null) {
159
                        throw new FeatureProviderNotFoundException(reference);
160
                }
161

    
162
                return featureProvider;
163
        }
164

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

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

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

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

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

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

    
236
        @Override
237
        public boolean allowWrite() {
238
                return false;
239
        }
240

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

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

    
254
        }
255

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

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

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

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

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

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

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

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

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

    
348
    /**
349
     * Override on providers that allow more than one geometry
350
     * 
351
     * @param geomname
352
     * @return
353
     * @throws DataException 
354
     */
355
    @Override
356
    public Envelope getEnvelope(String geomname) throws DataException {
357
        return getEnvelope();
358
    }
359
    
360
    
361

    
362
        /**
363
         * unsupported geometry write by default (return <code>false</code>),
364
         * override this otherwise
365
         *
366
         * @see org.gvsig.fmap.dal.feature.spi.FeatureStoreProvider#canWriteGeometry(int,
367
         *      int)
368
         */
369
        public boolean canWriteGeometry(int geometryType, int geometrySubType)
370
                        throws DataException {
371
                return false;
372
        }
373

    
374
        // --- Metadata methods ---
375

    
376
        public void delegate(DynObject dynObject) {
377
                if (this.metadata == null) {
378
                        return;
379
                }
380
                this.metadata.delegate(dynObject);
381
        }
382

    
383
        public DynClass getDynClass() {
384
                if (this.metadata == null) {
385
                        return null;
386
                }
387
                return this.metadata.getDynClass();
388
        }
389

    
390
        public Object getDynValue(String name) throws DynFieldNotFoundException {
391
                if (this.metadata == null) {
392
                        return null;
393
                }
394
                // TODO this.open??
395
                return this.metadata.getDynValue(name);
396
        }
397

    
398
        public boolean hasDynValue(String name) {
399
                if (this.metadata == null) {
400
                        return false;
401
                }
402
                // TODO this.open??
403
                return this.metadata.hasDynValue(name);
404
        }
405

    
406
    @Override
407
    public boolean hasDynMethod(String name) {
408
        if( metadata instanceof DynObject_v2 ) {
409
            return ((DynObject_v2)this.metadata).hasDynMethod(name);
410
        }
411
        return false;
412
    }
413

    
414
        public void implement(DynClass dynClass) {
415
                if (this.metadata == null) {
416
                        return;
417
                }
418
                this.metadata.implement(dynClass);
419

    
420
        }
421

    
422
        public Object invokeDynMethod(int code, Object[] args)
423
                        throws DynMethodException {
424
                if (this.metadata == null) {
425
                        return null;
426
                }
427
                // TODO this.open??
428
                return this.metadata.invokeDynMethod(this, code, args);
429
        }
430

    
431
        public Object invokeDynMethod(String name, Object[] args)
432
                        throws DynMethodException {
433
                if (this.metadata == null) {
434
                        return null;
435
                }
436
                // TODO this.open??
437
                return this.metadata.invokeDynMethod(this, name, args);
438
        }
439

    
440
        public void setDynValue(String name, Object value)
441
                        throws DynFieldNotFoundException {
442
                if (this.metadata == null) {
443
                        return;
444
                }
445
                // TODO this.open??
446
                this.metadata.setDynValue(name, value);
447
        }
448

    
449
        // --- end Metadata methods ---
450

    
451
        /**
452
         * unsupported by default, override this otherwise
453
         *
454
         * @see org.gvsig.fmap.dal.feature.spi.FeatureStoreProvider#allowAutomaticValues()
455
         */
456
        public boolean allowAutomaticValues() {
457
                return false;
458

    
459
        }
460

    
461
        /**
462
         * unsupported by default, override this otherwise
463
         *
464
         * @param featureProvider
465
         * @throws org.gvsig.fmap.dal.exception.DataException
466
         * @see org.gvsig.fmap.dal.feature.spi.FeatureStoreProvider#append(org.gvsig.
467
         *      fmap.dal.feature.spi.FeatureProvider)
468
         */
469
        @Override
470
        public void append(FeatureProvider featureProvider) throws DataException {
471
                // FIXME exception
472
                throw new UnsupportedOperationException();
473
        }
474

    
475
        /**
476
         * unsupported by default, override this otherwise
477
         *
478
         * @see org.gvsig.fmap.dal.feature.spi.FeatureStoreProvider#beginAppend()
479
         */
480
        public void beginAppend() throws DataException {
481
                // FIXME exception
482
                throw new UnsupportedOperationException();
483
        }
484

    
485
        public void beginAppend(int submode) throws DataException {
486
            this.beginAppend();
487
        }
488

    
489
        /**
490
         * unsupported by default, override this otherwise
491
         *
492
         * @see org.gvsig.fmap.dal.feature.spi.FeatureStoreProvider#endAppend()
493
         */
494
        public void endAppend() throws DataException {
495
                // FIXME exception
496
                throw new UnsupportedOperationException();
497
        }
498

    
499
        public void abortAppend() throws DataException {
500
                // FIXME exception
501
                throw new UnsupportedOperationException();
502
        }
503

    
504
        @Override
505
        public boolean supportsAppendMode() {
506
                return false;
507
        }
508

    
509
        @Override
510
        public UnmodifiableBasicMap<String,DataStore> getChildren() {
511
                return UnmodifiableBasicMap.EMPTY_UNMODIFIABLEBASICMAP;
512
        }
513

    
514
        @Override
515
        public StoresRepository getStoresRepository() {
516
            return null;
517
        }
518
        
519
        @Override
520
        public ResourcesStorage getResourcesStorage() {
521
            return null;
522
        }
523

    
524
        /**
525
         * unsupported by default (return null), override this otherwise
526
         *
527
         * @throws org.gvsig.fmap.dal.exception.ReadException
528
         * @throws org.gvsig.fmap.dal.exception.ValidateDataParametersException
529
         * @see org.gvsig.fmap.dal.spi.DataStoreProvider#getExplorer()
530
         */
531
        @Override
532
        public DataServerExplorer getExplorer() throws ReadException,
533
                        ValidateDataParametersException {
534
                return null;
535
        }
536

    
537
        public void clear() {
538
                if (metadata != null) {
539
                        metadata.clear();
540
                }
541
        }
542

    
543
        /**
544
         * Returns a {@link FeatureProvider} by reference, using the provided
545
         * {@link FeatureType}. This is the child classes implementation of the
546
         * {@link #getFeatureProviderByReference(FeatureReferenceProviderServices)}
547
         * method.
548
         *
549
         * @param reference
550
         *            the reference to the {@link FeatureProvider}
551
         * @param featureType
552
         *            the type of feature to load
553
         * @return the {@link FeatureProvider} being referenced
554
         * @throws DataException
555
         *             if there is an error loading the {@link FeatureProvider}
556
         */
557
        protected abstract FeatureProvider internalGetFeatureProviderByReference(
558
                        FeatureReferenceProviderServices reference, FeatureType featureType)
559
                        throws DataException;
560

    
561
        public static class FeatureProviderNotFoundException extends DataException {
562

    
563
                private static final long serialVersionUID = 5161749797695723151L;
564

    
565
                public FeatureProviderNotFoundException(FeatureReference reference) {
566
                        super("Cannot retreive FeatureProvider for reference %(reference)",
567
                                        "_FeatureProviderNotFoundException", serialVersionUID);
568
                        setValue("reference", reference.toString());
569
                }
570
        }
571

    
572
        public boolean isKnownEnvelope(){
573
            return true;
574
        }
575

    
576
    public boolean hasRetrievedFeaturesLimit(){
577
        return false;
578
    }
579

    
580
    public int getRetrievedFeaturesLimit(){
581
        return -1;
582
    }
583

    
584
    public Interval getInterval() {
585
        return null;
586
    }
587

    
588
    public Collection getTimes() {
589
        // TODO Auto-generated method stub
590
        return null;
591
    }
592

    
593
    public Collection getTimes(Interval interval) {
594
        // TODO Auto-generated method stub
595
        return null;
596
    }
597

    
598
    @Override
599
    public ExpressionBuilder createExpression() {
600
        ExpressionBuilder builder = ExpressionEvaluatorLocator.getManager().createExpressionBuilder();
601
        return builder;
602
    }
603

    
604
    protected void savePrjFile(File dataFile, IProjection proj){
605
        File file = new File(FilenameUtils.removeExtension(dataFile.getAbsolutePath())+".prj");
606
        try {
607
            String export = proj.export(ICRSFactory.FORMAT_WKT_ESRI);
608
            if(export!=null){
609
                OutputStream os = null;
610
                try {
611
                    os = new BufferedOutputStream(FileUtils.openOutputStream(file));
612
                    IOUtils.write(export, os, StandardCharsets.UTF_8);
613
                } finally {
614
                    IOUtils.closeQuietly(os);
615
                }
616
            }
617
        } catch (Exception e) {
618
            logger.info("Can't write prj file '" + file.getAbsolutePath() + "'.");
619
        }
620
    }
621

    
622
    @Override
623
    public boolean isTemporary() {
624
        return false;
625
    }
626

    
627
    @Override
628
    public void fixFeatureTypeFromParameters() {
629
        
630
    }
631

    
632
    @Override
633
    public boolean supportsPassThroughMode() {
634
        return false;
635
    }
636

    
637
    @Override
638
    public void passThroughInsert(FeatureProvider featureProvider) throws DataException {
639
        throw new UnsupportedOperationException();
640
    }
641

    
642
    @Override
643
    public void passThroughInsertOrUpdate(FeatureProvider featureProvider) throws DataException {
644
        throw new UnsupportedOperationException();
645
    }
646

    
647
    @Override
648
    public void passThroughUpdate(FeatureProvider featureProvider) throws DataException {
649
        throw new UnsupportedOperationException();
650
    }
651
    
652
    @Override
653
    public void passThroughDelete(FeatureReferenceProviderServices featureReference) throws DataException {
654
        throw new UnsupportedOperationException();
655
    }
656
    
657
    @Override
658
    public void passThroughDelete(Expression filter) throws DataException {
659
        throw new UnsupportedOperationException();
660
    }
661
    
662
    @Override
663
    public void passThroughUpdate(Object[] parameters, Expression filter){
664
        throw new UnsupportedOperationException();
665
    }
666

    
667
    @Override
668
    public String toString() {
669
        try {
670
            ToStringBuilder builder = new ToStringBuilder(this);
671
            builder.append("parameters", this.parameters, true);
672
            return builder.toString();
673
        } catch (Exception e) {
674
            return super.toString();
675
        }
676
    }
677

    
678
    @Override
679
    public FeatureSetProvider createSet(FeatureQuery query, FeatureType providerFeatureType, FeatureType storeFeatureType) throws DataException {
680
        return this.createSet(query, storeFeatureType);
681
    }
682

    
683
}