Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.compat.cdc / org.gvsig.fmap.dal / org.gvsig.fmap.dal.impl / src / main / java / org / gvsig / fmap / dal / raster / impl / DefaultRasterStore.java @ 44831

History | View | Annotate | Download (35.4 KB)

1
/* gvSIG. Desktop Geographic Information System.
2
 *
3
 * Copyright ? 2007-2016 gvSIG Association
4
 *
5
 * This program is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU General Public License
7
 * as published by the Free Software Foundation; either version 2
8
 * of the License, or (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, write to the Free Software
17
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
18
 * MA  02110-1301, USA.
19
 *
20
 * For any additional information, do not hesitate to contact us
21
 * at info AT gvsig.com, or visit our website www.gvsig.com.
22
 */
23
package org.gvsig.fmap.dal.raster.impl;
24

    
25
import java.util.ArrayList;
26
import java.util.Collection;
27
import java.util.HashMap;
28
import java.util.List;
29
import java.util.Map;
30
import java.util.Map.Entry;
31
import java.util.Set;
32

    
33
import org.cresques.cts.IProjection;
34
import org.gvsig.fmap.dal.BaseStoresRepository;
35
import org.slf4j.Logger;
36
import org.slf4j.LoggerFactory;
37

    
38
import org.gvsig.fmap.dal.DALLocator;
39
import org.gvsig.fmap.dal.DataManager;
40
import org.gvsig.fmap.dal.DataParameters;
41
import org.gvsig.fmap.dal.DataQuery;
42
import org.gvsig.fmap.dal.DataServerExplorer;
43
import org.gvsig.fmap.dal.DataSet;
44
import org.gvsig.fmap.dal.DataStore;
45
import org.gvsig.fmap.dal.DataStoreNotification;
46
import org.gvsig.fmap.dal.DataStoreParameters;
47
import org.gvsig.fmap.dal.DataStoreProviderFactory;
48
import org.gvsig.fmap.dal.StoresRepository;
49
import org.gvsig.fmap.dal.exception.CloneException;
50
import org.gvsig.fmap.dal.exception.DataException;
51
import org.gvsig.fmap.dal.exception.InitializeException;
52
import org.gvsig.fmap.dal.exception.ProviderNotRegisteredException;
53
import org.gvsig.fmap.dal.exception.ValidateDataParametersException;
54
import org.gvsig.fmap.dal.feature.exception.PersistenceStoreAlreadyLoadedException;
55
import org.gvsig.fmap.dal.impl.DefaultDataManager;
56
import org.gvsig.fmap.dal.raster.RasterStoreProviderFactory;
57
import org.gvsig.fmap.dal.raster.BandAttributeDescriptor;
58
import org.gvsig.fmap.dal.raster.BandDescriptor;
59
import org.gvsig.fmap.dal.raster.BandQuery;
60
import org.gvsig.fmap.dal.raster.RasterCache;
61
import org.gvsig.fmap.dal.raster.RasterQuery;
62
import org.gvsig.fmap.dal.raster.RasterSet;
63
import org.gvsig.fmap.dal.raster.RasterStore;
64
import org.gvsig.fmap.dal.raster.RasterStoreNotification;
65
import org.gvsig.fmap.dal.raster.exceptions.RasterQueryCloneException;
66
import org.gvsig.fmap.dal.raster.impl.exceptions.AddingBandsException;
67
import org.gvsig.fmap.dal.raster.spi.RasterCacheStoreProvider;
68
import org.gvsig.fmap.dal.raster.spi.RasterStoreProvider;
69
import org.gvsig.fmap.dal.raster.spi.RasterStoreProviderServices;
70
import org.gvsig.fmap.dal.resource.Resource;
71
import org.gvsig.fmap.dal.resource.spi.ResourceProvider;
72
import org.gvsig.fmap.dal.spi.DALSPILocator;
73
import org.gvsig.fmap.dal.spi.DataManagerProviderServices;
74
import org.gvsig.fmap.dal.spi.DataStoreInitializer2;
75
import org.gvsig.fmap.geom.exception.CreateEnvelopeException;
76
import org.gvsig.fmap.geom.primitive.Envelope;
77
import org.gvsig.metadata.MetadataLocator;
78
import org.gvsig.metadata.MetadataManager;
79
import org.gvsig.metadata.exceptions.MetadataException;
80
import org.gvsig.raster.lib.buffer.api.Band;
81
import org.gvsig.raster.lib.buffer.api.Buffer;
82
import org.gvsig.raster.lib.buffer.api.BufferDimensions;
83
import org.gvsig.raster.lib.buffer.api.exceptions.BufferException;
84
import org.gvsig.timesupport.Interval;
85
import org.gvsig.tools.ToolsLocator;
86
import org.gvsig.tools.dispose.DisposeUtils;
87
import org.gvsig.tools.dispose.impl.AbstractDisposable;
88
import org.gvsig.tools.dynobject.DelegatedDynObject;
89
import org.gvsig.tools.dynobject.DynClass;
90
import org.gvsig.tools.dynobject.DynObject;
91
import org.gvsig.tools.dynobject.DynObjectManager;
92
import org.gvsig.tools.dynobject.DynObject_v2;
93
import org.gvsig.tools.dynobject.DynStruct;
94
import org.gvsig.tools.dynobject.exception.DynFieldNotFoundException;
95
import org.gvsig.tools.dynobject.exception.DynMethodException;
96
import org.gvsig.tools.exception.BaseException;
97
import org.gvsig.tools.locator.LocatorException;
98
import org.gvsig.tools.observer.Observable;
99
import org.gvsig.tools.observer.Observer;
100
import org.gvsig.tools.observer.impl.DelegateWeakReferencingObservable;
101
import org.gvsig.tools.persistence.PersistenceManager;
102
import org.gvsig.tools.persistence.PersistentState;
103
import org.gvsig.tools.persistence.exception.PersistenceException;
104
import org.gvsig.tools.resourcesstorage.ResourcesStorage;
105
import org.gvsig.tools.util.UnmodifiableBasicMap;
106
import org.gvsig.tools.visitor.Visitor;
107

    
108
/**
109
 * Implements RasterStore
110
 *
111
 */
112
@SuppressWarnings("UseSpecificCatch")
113
public class DefaultRasterStore extends AbstractDisposable implements DataStoreInitializer2,
114
    RasterStoreProviderServices, RasterStore, Observer {
115

    
116
    private static final Logger LOGGER = LoggerFactory.getLogger(DefaultRasterStore.class);
117

    
118
    private static final String PERSISTENCE_DEFINITION_NAME = "RasterStore";
119
    private static final String METADATA_DEFINITION_NAME = "RasterStore";
120

    
121
    private DataStoreParameters parameters = null;
122
    private RasterStoreProvider provider = null;
123
    private DelegatedDynObject metadata;
124
    private DefaultDataManager dataManager = null;
125
    private List<BandsFromStore> additionalBands = null;
126

    
127
    private DelegateWeakReferencingObservable delegateObservable = new DelegateWeakReferencingObservable(this);
128

    
129
    /**
130
     * Registers persistence
131
     */
132
    public static void registerPersistenceDefinition() {
133
        PersistenceManager manager = ToolsLocator.getPersistenceManager();
134
        if (manager.getDefinition(PERSISTENCE_DEFINITION_NAME) == null) {
135
            DynStruct definition =
136
                manager.addDefinition(DefaultRasterStore.class, PERSISTENCE_DEFINITION_NAME,
137
                    PERSISTENCE_DEFINITION_NAME + " Persistent definition", null, null);
138
            definition.addDynFieldString("dataStoreName").setMandatory(true).setPersistent(true);
139

    
140
            definition.addDynFieldObject("parameters").setClassOfValue(DynObject.class).setMandatory(true)
141
                .setPersistent(true);
142
        }
143
    }
144

    
145
    /**
146
     * Registers metadata
147
     *
148
     * @throws MetadataException
149
     */
150
    public static void registerMetadataDefinition() throws MetadataException {
151
        MetadataManager manager = MetadataLocator.getMetadataManager();
152
        if (manager.getDefinition(METADATA_DEFINITION_NAME) == null) {
153
            DynStruct metadataDefinition = manager.addDefinition(METADATA_DEFINITION_NAME, null);
154
            metadataDefinition.extend(manager.getDefinition(DataStore.METADATA_DEFINITION_NAME));
155
        }
156
    }
157

    
158
    /**
159
     * @return dataManager
160
     */
161
    @Override
162
    public DataManager getManager() {
163
        return this.dataManager;
164
    }
165

    
166
    @Override
167
    public String getName() {
168
        return this.provider.getName();
169
    }
170

    
171
    @Override
172
    public String getFullName() {
173
        return this.provider.getFullName();
174
    }
175

    
176
    @Override
177
    public DataStoreParameters getParameters() {
178
        return parameters;
179
    }
180

    
181
    @Override
182
    public String getProviderName() {
183
        return this.provider.getProviderName();
184
    }
185

    
186
    @Override
187
    public void refresh() throws DataException {
188
        this.notifyChange(RasterStoreNotification.BEFORE_REFRESH);
189
        this.provider.refresh();
190
        this.notifyChange(RasterStoreNotification.AFTER_REFRESH);
191
    }
192

    
193
    @Override
194
    public DataSet getDataSet() throws DataException {
195
        return this.getRasterSet();
196
    }
197

    
198
    @Override
199
    public DataSet getDataSet(DataQuery dataQuery) throws DataException {
200
        return this.getRasterSet((RasterQuery) dataQuery);
201
    }
202

    
203
    @Override
204
    public void getDataSet(Observer observer) throws DataException {
205
        this.getRasterSet(null, observer);
206
    }
207

    
208
    @Override
209
    public void getDataSet(DataQuery dataQuery, Observer observer) throws DataException {
210
        this.getRasterSet((RasterQuery) dataQuery, observer);
211
    }
212

    
213
    @Override
214
    public RasterSet getRasterSet(RasterQuery rasterQuery) throws DataException {
215

    
216
        try {
217
            if (rasterQuery != null) {
218
                List<BandQuery> queryBands = rasterQuery.getBands();
219
                if (!queryBands.isEmpty()) {
220
                    RasterQuery mainRasterQuery = (RasterQuery) rasterQuery.clone();
221
                    mainRasterQuery.clearBands();
222
                    Map<RasterStore, RasterQuery> rasterQueries = new HashMap<>();
223

    
224
                    for (BandQuery bandQuery : queryBands) {
225
                        int band = bandQuery.getBand();
226
                        if(band<getProvider().getBands()){
227
                            mainRasterQuery.addBand(bandQuery);
228
                        } else {
229
                            int bandCounter = getProvider().getBands();
230
                            boolean bandFound = false;
231
                            if(additionalBands!=null){
232
                                for (BandsFromStore bandsFromStore : additionalBands) {
233
                                    RasterStore store = bandsFromStore.getStore();
234

    
235
                                    if (band < bandCounter + bandsFromStore.size()) {
236
                                        BandQuery storeBandQuery =
237
                                            store.createBandQuery(bandsFromStore.get(band - bandCounter));
238
                                        if (rasterQueries.containsKey(store)) {
239
                                            rasterQueries.get(store).addBand(storeBandQuery);
240
                                        } else {
241
                                            RasterQuery storeRasterQuery = (RasterQuery) rasterQuery.clone();
242
                                            storeRasterQuery.clearBands();
243
                                            storeRasterQuery.addBand(storeBandQuery);
244
                                            rasterQueries.put(store, storeRasterQuery);
245
                                            bandFound = true;
246
                                        }
247
                                    }
248
                                    bandCounter += bandsFromStore.size();
249
                                    if (bandFound) {
250
                                        break;
251
                                    }
252
                                }
253
                            }
254
                        }
255
                    }
256

    
257
                    RasterSet mainRasterSet = new DefaultRasterSet(this, mainRasterQuery);
258
                    for (Entry<RasterStore, RasterQuery> entry : rasterQueries.entrySet()) {
259
                        RasterStore store = entry.getKey();
260
                        RasterQuery query = entry.getValue();
261
                        RasterSet subRasterSet = store.getRasterSet(query);
262
                        for (Band band : subRasterSet) {
263
                            mainRasterSet.addBand(band);
264
                        }
265
                    }
266
                    return mainRasterSet;
267
                }
268
            }
269
            RasterSet mainRasterSet = new DefaultRasterSet(this, rasterQuery);
270
            if (additionalBands != null) {
271
                for (BandsFromStore bandsFromStore : additionalBands) {
272
                    RasterStore store = bandsFromStore.getStore();
273
                    RasterQuery subRasterQuery = store.createRasterQuery();
274
                    if( rasterQuery!=null ) {
275
                      subRasterQuery.setClip(rasterQuery.getClip());
276
                      subRasterQuery.setScale(rasterQuery.getScale());
277
                    }
278
                    subRasterQuery.setPixelSize(mainRasterSet.getDimensions().getPixelSizeX());
279
                    for (int i = 0; i < bandsFromStore.size(); i++) {
280
                        BandQuery bandQuery = store.createBandQuery(bandsFromStore.get(i));
281
                        subRasterQuery.addBand(bandQuery);
282
                    }
283
                    DefaultRasterSet subRasterSet = new DefaultRasterSet(store, subRasterQuery);
284
                    if(subRasterSet.getColumns()!=mainRasterSet.getColumns() || subRasterSet.getRows()!=mainRasterSet.getRows()){
285
                        Buffer subBuffer = subRasterSet.createInterpolated(mainRasterSet.getRows(), mainRasterSet.getColumns(), Buffer.INTERPOLATION_NearestNeighbour, null);
286
                        for (Band band : subBuffer) {
287
                            mainRasterSet.addBand(band);
288
                        }
289
                    } else {
290
                        for (Band band : subRasterSet) {
291
                            mainRasterSet.addBand(band);
292
                        }
293
                    }
294
                    DisposeUtils.disposeQuietly(subRasterSet);
295
                }
296
            }
297
            return mainRasterSet;
298
        } catch (Exception e) {
299
            throw new RasterQueryCloneException(e);
300
        }
301
    }
302

    
303
    @Override
304
    public RasterSet getRasterSet() throws DataException {
305
        return getRasterSet(createRasterQuery());
306
    }
307

    
308
    /**
309
     * Adds an observer to the DataSet
310
     *
311
     * @param observer
312
     * @throws DataException
313
     */
314
    @Override
315
    public void getRasterSet(Observer observer) throws DataException {
316
        RasterSet set = this.getRasterSet();
317
        set.addObserver(observer);
318
    }
319

    
320
    /**
321
     * Adds an observer to the queried DataSet
322
     *
323
     * @param rasterQuery
324
     * @param observer
325
     * @throws DataException
326
     */
327
    @Override
328
    public void getRasterSet(RasterQuery rasterQuery, Observer observer) throws DataException {
329
        RasterSet set = this.getRasterSet(rasterQuery);
330
        set.addObserver(observer);
331
    }
332

    
333
    @Override
334
    public void accept(Visitor visitor) throws BaseException {
335
        RasterSet set = getRasterSet();
336
        try {
337
            set.accept(visitor);
338
        } finally {
339
            set.dispose();
340
        }
341
    }
342

    
343
    @Override
344
    public void accept(Visitor visitor, DataQuery dataQuery) throws BaseException {
345
        RasterSet set = getRasterSet((RasterQuery) dataQuery);
346
        try {
347
            set.accept(visitor);
348
        } finally {
349
            set.dispose();
350
        }
351

    
352
    }
353

    
354
    @Override
355
    public DataSet getSelection() throws DataException {
356
        // TODO Auto-generated method stub
357
        return null;
358
    }
359

    
360
    @Override
361
    public void setSelection(DataSet selection) throws DataException {
362
        // TODO Auto-generated method stub
363

    
364
    }
365

    
366
    @Override
367
    public DataSet createSelection() throws DataException {
368
        // TODO Auto-generated method stub
369
        return null;
370
    }
371

    
372
    @Override
373
    public UnmodifiableBasicMap<String,DataStore> getChildren() {
374
        UnmodifiableBasicMap<String, DataStore> children = this.provider.getChildren();
375
        if( children == null ) {
376
            return UnmodifiableBasicMap.EMPTY_UNMODIFIABLEBASICMAP;
377
        }
378
        return children;
379
    }
380

    
381
    @Override
382
    public DataServerExplorer getExplorer() throws DataException, ValidateDataParametersException {
383
        return this.provider.getExplorer();
384
    }
385

    
386
    @Override
387
    public DataQuery createQuery() {
388
        return createRasterQuery();
389
    }
390

    
391
    @Override
392
    public Interval getInterval() {
393
        return this.provider.getInterval();
394
    }
395

    
396
    @Override
397
    public Collection<?> getTimes() {
398
        return this.provider.getTimes();
399
    }
400

    
401
    @Override
402
    public Collection<?> getTimes(Interval interval) {
403
        return this.provider.getTimes(interval);
404
    }
405

    
406
    @Override
407
    public void disableNotifications() {
408
        this.delegateObservable.disableNotifications();
409
    }
410

    
411
    @Override
412
    public void enableNotifications() {
413
        this.delegateObservable.enableNotifications();
414

    
415
    }
416

    
417
    @Override
418
    public void beginComplexNotification() {
419
        this.delegateObservable.beginComplexNotification();
420

    
421
    }
422

    
423
    @Override
424
    public void endComplexNotification() {
425
        this.delegateObservable.endComplexNotification();
426
    }
427

    
428
    @Override
429
    public void addObserver(Observer observer) {
430
        if (delegateObservable != null) {
431
            this.delegateObservable.addObserver(observer);
432
        }
433
    }
434

    
435
    @Override
436
    public void deleteObserver(Observer observer) {
437
        if (delegateObservable != null) {
438
            this.delegateObservable.deleteObserver(observer);
439
        }
440

    
441
    }
442

    
443
    @Override
444
    public void deleteObservers() {
445
        this.delegateObservable.deleteObservers();
446
    }
447

    
448
    @Override
449
    public void saveToState(PersistentState state) throws PersistenceException {
450

    
451
        state.set("dataStoreName", this.getName());
452
        state.set("parameters", this.parameters);
453
    }
454

    
455
    @Override
456
    public void loadFromState(PersistentState state) throws PersistenceException {
457
        if (this.provider != null) {
458
            throw new PersistenceStoreAlreadyLoadedException(this.getName());
459
        }
460
        if (this.getManager() == null) {
461
            this.dataManager = (DefaultDataManager) DALLocator.getDataManager();
462
        }
463

    
464
        DataStoreParameters params = (DataStoreParameters) state.get("parameters");
465

    
466
        try {
467

    
468
            this.intialize(this.dataManager, params);
469
            this.setProvider(this.provider);
470

    
471
        } catch (Exception e) {
472
            throw new PersistenceException(e);
473
        }
474

    
475
    }
476

    
477
    //
478
    // ====================================================================
479
    // Metadata related methods
480
    //
481

    
482
    @Override
483
    public Set<?> getMetadataChildren() throws MetadataException {
484
        // TODO Auto-generated method stub
485
        return null;
486
    }
487

    
488
    @Override
489
    public Object getMetadataID() throws MetadataException {
490
        return this.provider.getSourceId();
491
    }
492

    
493
    @Override
494
    public String getMetadataName() throws MetadataException {
495
        return this.provider.getProviderName();
496
    }
497

    
498
    @Override
499
    public DynClass getDynClass() {
500
        return this.metadata.getDynClass();
501
    }
502

    
503
    @Override
504
    public void implement(DynClass dynClass) {
505
        this.metadata.implement(dynClass);
506
    }
507

    
508
    @Override
509
    public void delegate(DynObject dynObject) {
510
        this.metadata.delegate(dynObject);
511
    }
512

    
513
    @Override
514
    public Object getDynValue(String name) throws DynFieldNotFoundException {
515
        if (this.metadata.hasDynValue(name)) {
516
            return this.metadata.getDynValue(name);
517
        }
518
        if (METADATA_PROVIDER.equalsIgnoreCase(name)) {
519
            return this.provider.getProviderName();
520
        } else if (METADATA_CONTAINERNAME.equalsIgnoreCase(name)) {
521
            return this.provider.getSourceId();
522
        }
523
        return this.metadata.getDynValue(name);
524
    }
525

    
526
    @Override
527
    public void setDynValue(String name, Object value) throws DynFieldNotFoundException {
528

    
529
        this.metadata.setDynValue(name, value);
530

    
531
    }
532

    
533
    @Override
534
    public boolean hasDynValue(String name) {
535
        return this.metadata.hasDynValue(name);
536
    }
537

    
538
    @Override
539
    public Object invokeDynMethod(String name, Object[] args) throws DynMethodException {
540
        return this.metadata.invokeDynMethod(this, name, args);
541
    }
542

    
543
    @Override
544
    public Object invokeDynMethod(int code, Object[] args) throws DynMethodException {
545
        return this.metadata.invokeDynMethod(this, code, args);
546
    }
547

    
548
    @Override
549
    public void clear() {
550
        if (metadata != null) {
551
            metadata.clear();
552
        }
553
    }
554

    
555
    @Override
556
    public RasterQuery createRasterQuery() {
557
        return new DefaultRasterQuery();
558
    }
559

    
560
    @Override
561
    public DataStore getStore() {
562
        return this;
563
    }
564

    
565
    @Override
566
    public void update(Observable observable, Object notification) {
567
        if (observable instanceof DataSet) {
568
            this.notifyChange(RasterStoreNotification.DATASET_CHANGED);
569

    
570
        } else {
571
            if (observable instanceof RasterStoreProvider) {
572
                if (observable == this.provider) {
573
                    this.notifyChange(RasterStoreNotification.STORE_PROVIDER_CHANGED);
574
                }
575
            }
576
        }
577
    }
578

    
579
    @Override
580
    protected void doDispose() throws BaseException {
581

    
582
        LOGGER.debug("Dispose DefaultRasterStore '"+this.getFullName()+"'");
583

    
584
        this.notifyChange(DataStoreNotification.BEFORE_DISPOSE);
585
        DisposeUtils.dispose(this.provider);
586
        this.provider = null;
587
        this.parameters = null;
588
        if(additionalBands!=null){
589
          for (BandsFromStore bandsFromStore : additionalBands) {
590
            DisposeUtils.dispose(bandsFromStore);
591
          }
592
            this.additionalBands = null;
593
        }
594

    
595
        this.notifyChange(DataStoreNotification.AFTER_DISPOSE);
596
        if (delegateObservable != null) {
597
            this.delegateObservable.deleteObservers();
598
            this.delegateObservable = null;
599
        }
600
    }
601

    
602
    @Override
603
    public Object clone() throws CloneNotSupportedException {
604
        DataStoreParameters dsp = getParameters();
605

    
606
        DefaultRasterStore cloned_store = null;
607

    
608
        try {
609
            cloned_store = (DefaultRasterStore) DALLocator.getDataManager().openStore(this.getProviderName(), dsp);
610
            cloned_store.additionalBands = new ArrayList<>(additionalBands);
611
        } catch (Exception e) {
612
            throw new CloneException(e);
613
        }
614
        return cloned_store;
615

    
616
    }
617

    
618
    /**
619
     * Notifies change
620
     *
621
     * @param notification
622
     */
623
    public void notifyChange(String notification) {
624
        if (delegateObservable != null) {
625
            notifyChange(new DefaultRasterStoreNotification(this, notification));
626
        }
627

    
628
    }
629

    
630
    @Override
631
    public void notifyChange(String notification, ResourceProvider data) {
632
        notifyChange(new DefaultRasterStoreNotification(this, DataStoreNotification.RESOURCE_CHANGED));
633
    }
634

    
635
    /**
636
     * Notifies change
637
     *
638
     * @param storeNotification
639
     */
640
    public void notifyChange(DefaultRasterStoreNotification storeNotification) {
641
        try {
642
            delegateObservable.notifyObservers(storeNotification);
643
        } catch (Exception e) {
644
            LOGGER.warn("Problems notifying changes in store '"+getName()+"'.", e);
645
        }
646
    }
647

    
648
    /**
649
     * Gets this provider
650
     *
651
     * @return RasterStoreProvider
652
     */
653
    @Override
654
    public RasterStoreProvider getProvider() {
655
        return this.provider;
656
    }
657

    
658
    @Override
659
    public Envelope getEnvelope() throws DataException, LocatorException, CreateEnvelopeException {
660
        return getDimensions().getEnvelope();
661
    }
662

    
663
    @Override
664
    public List<BandDescriptor> getBandDescriptors() {
665
        List<BandDescriptor> bands = new ArrayList<>();
666
        for( int i=0; i<this.getBands(); i++ ) {
667
            bands.add(this.getBandDescriptor(i));
668
        }
669
        return bands;
670
    }
671

    
672
    @Override
673
    public BandDescriptor getBandDescriptor(int band) {
674
        int bandsCounter = this.provider.getBands();
675
        if(band<bandsCounter){
676
            return this.provider.getBandDescriptor(band);
677
        }
678

    
679
        if(additionalBands!=null){
680
            for (BandsFromStore bandsFromStore : additionalBands) {
681
                if((band-bandsCounter)<bandsFromStore.bands.size()){
682
                    return bandsFromStore.getBandDescriptor(band-bandsCounter);
683
                }
684
                bandsCounter+=bandsFromStore.size();
685
            }
686
        }
687
        return null;
688
    }
689

    
690
    @Override
691
    public BandQuery createBandQuery(int band) {
692
        return new DefaultBandQuery(band, getBandDescriptor(band));
693
    }
694

    
695
    @Override
696
    public int getBands() {
697
        int bands = this.provider.getBands();
698
        if(additionalBands!=null){
699
            for (BandsFromStore bandsFromStore : additionalBands) {
700
                bands+=bandsFromStore.size();
701
            }
702
        }
703
        return bands;
704
    }
705

    
706
    @Override
707
    public BandDescriptor createBandDescriptor(int band, List<BandAttributeDescriptor> attributes) {
708
        return new DefaultBandDescriptor(this, band, attributes);
709
    }
710

    
711
    @Override
712
    public BandAttributeDescriptor createBandAttributeDescriptor(int band, String name, String description,
713
        List<Object> values, String units) {
714
        return new DefaultBandAttributeDescriptor(band, name, description, values, units);
715
    }
716

    
717
    @Override
718
    public BandAttributeDescriptor createBandAttributeDescriptor(int band, String name, Object value, String description,
719
        List<Object> values, String units) {
720
        return new DefaultBandAttributeDescriptor(band, name, value, description, values, units);
721
    }
722

    
723
    @Override
724
    public BandAttributeDescriptor createBandAttributeDescriptor(int band, String name, String description,
725
        List<Object> values) {
726
        return new DefaultBandAttributeDescriptor(band, name, description, values);
727
    }
728

    
729
    @Override
730
    public void notifyChange(String notification, Resource resource) {
731
        notifyChange(new DefaultRasterStoreNotification(this, DataStoreNotification.RESOURCE_CHANGED));
732
    }
733

    
734
    @Override
735
    public RasterStore getRasterStore() {
736
        return this;
737
    }
738

    
739
    @Override
740
    public void useCache(String providerName, DynObject parameters) throws DataException {
741

    
742
        if (providerName == null) {
743
            throw new InitializeException("It is necessary to provide a cache name", null);
744
        }
745
        if (parameters == null) {
746
            throw new InitializeException("It is necessary to provide parameters to create the explorer", null);
747
        }
748

    
749
        DataManagerProviderServices manager = DALSPILocator.getDataManagerProviderServices();
750
        RasterStoreProviderFactory providerFactory =
751
            (RasterStoreProviderFactory) manager.getStoreProviderFactory(providerName);
752

    
753
        if (providerFactory == null) {
754
            throw new ProviderNotRegisteredException(providerName);
755
        }
756

    
757
        RasterCacheStoreProvider cache =
758
            (RasterCacheStoreProvider) providerFactory.createProvider((DataParameters) parameters, this);
759

    
760
        RasterQuery rasterQuery = this.createRasterQuery();
761
        cache.apply(provider,
762
            (IProjection) this.getParameters().getDynValue(DataStore.METADATA_CRS), rasterQuery);
763
        this.provider = cache;
764
    }
765

    
766
    @Override
767
    public RasterCache getCache() {
768
        if(this.provider instanceof RasterCache){
769
            return (RasterCache) this.provider;
770
        }
771
        return null;
772
    }
773

    
774
    @Override
775
    public void intialize(DataManager dataManager, DataStoreParameters parameters) throws InitializeException {
776

    
777
        DynObjectManager dynManager = ToolsLocator.getDynObjectManager();
778

    
779
        this.metadata =
780
            (DelegatedDynObject) dynManager.createDynObject(METADATA_DEFINITION_NAME,
781
                MetadataManager.METADATA_NAMESPACE);
782

    
783
        this.dataManager = (DefaultDataManager) dataManager;
784

    
785
        this.parameters = parameters;
786

    
787
    }
788

    
789
    @Override
790
    public void setProvider(org.gvsig.fmap.dal.DataStoreProvider provider) {
791
        if(this.provider != null){
792
            throw new IllegalStateException("Provider already set.");
793
        }
794
        this.provider = (RasterStoreProvider) provider;
795
        // FIXME: habr?a que hacer un bind del provider y a?adir un dispose en el openStore del DataManager
796
//        DisposeUtils.bind(this.provider);
797
        this.delegate(this.provider);
798
    }
799

    
800
    @Override
801
    public void addBand(RasterStore store, int band) throws DataException {
802
        if(store.equals(this)){
803
            LOGGER.warn("Can't add bands that belong to this same store.");
804
            throw new IllegalArgumentException("Can't add bands that belong to this same store.");
805
        }
806

    
807
        try {
808
            if(!store.getEnvelope().equals(this.getEnvelope())){
809
                LOGGER.warn("The envelopes are differents.");
810
                throw new AddingBandsException(store.getName(), this.getName(), "The envelopes are differents.", null);
811
            }
812
        } catch (LocatorException | DataException | CreateEnvelopeException e) {
813
            LOGGER.warn("Can't compare the envelopes.",e);
814
            throw new AddingBandsException(store.getName(), this.getName(), "Can't compare the envelopes.", e);
815
        }
816

    
817
        if(!store.getParameters().getDynValue(METADATA_CRS).equals(this.getParameters().getDynValue(METADATA_CRS))){
818
            throw new AddingBandsException(store.getName(), this.getName(), "The projections are differents.", null);
819
        }
820

    
821
        if(additionalBands==null){
822
            this.additionalBands = new ArrayList<>();
823
        }
824

    
825
        boolean found = false;
826
      for (BandsFromStore bandsFromStore : additionalBands) {
827
        if(bandsFromStore.getStore().equals(store)){
828
          found = true;
829
          if(bandsFromStore.contains(band)){
830
            LOGGER.warn("The band '"+band+"' of the store '"+store.getName()+"' is already added to the additional bands.");
831
          } else {
832
            bandsFromStore.add(band);
833
          }
834
          break;
835
        }
836
      }
837
        if(!found){
838
            BandsFromStore bandsFromStore = new BandsFromStore(store);
839
            bandsFromStore.add(band);
840
            this.additionalBands.add(bandsFromStore);
841
        }
842
    }
843

    
844
    @Override
845
    public void addBands(RasterStore store, List<Integer> bands) throws DataException {
846
        if(store.equals(this)){
847
            LOGGER.warn("Can't add bands that belong to this same store.");
848
            throw new IllegalArgumentException("Can't add bands that belong to this same store.");
849
        }
850

    
851
        try {
852
            if(!store.getEnvelope().equals(this.getEnvelope())){
853
                LOGGER.warn("The envelopes are differents.");
854
                throw new AddingBandsException(store.getName(), this.getName(), "The envelopes are differents.", null);
855
            }
856
        } catch (LocatorException | DataException | CreateEnvelopeException e) {
857
            LOGGER.warn("Can't compare the envelopes.",e);
858
            throw new AddingBandsException(store.getName(), this.getName(), "Can't compare the envelopes.", e);
859
        }
860

    
861
        if(!store.getParameters().getDynValue(METADATA_CRS).equals(this.getParameters().getDynValue(METADATA_CRS))){
862
            throw new AddingBandsException(store.getName(), this.getName(), "The projections are differents.", null);
863
        }
864

    
865
        if(additionalBands==null){
866
            this.additionalBands = new ArrayList<>();
867
        }
868

    
869
        boolean found = false;
870
        for (BandsFromStore bandsFromStore : additionalBands) {
871
            if(bandsFromStore.getStore().equals(store)){
872
                found = true;
873
              for (Integer band : bands) {
874
                bandsFromStore.add(band);
875
              }
876
            }
877
        }
878
        if(!found){
879
            BandsFromStore bandsFromStore = new BandsFromStore(store, bands);
880
            this.additionalBands.add(bandsFromStore);
881
        }
882
    }
883

    
884
    @Override
885
    public void clearAdditionalBands() {
886
        if (this.additionalBands != null) {
887
            for (BandsFromStore bandsFromStore : additionalBands) {
888
                DisposeUtils.dispose(bandsFromStore);
889
            }
890
        }
891
        this.additionalBands = null;
892
    }
893

    
894
    @Override
895
    public void removeBand(int band) {
896
        if(band<getProvider().getBands()){
897
            throw new IllegalArgumentException("Can't remove bands of main store.");
898
        }
899
        int bandCounter = getProvider().getBands();
900
        int storeCounter = 0;
901
        while(bandCounter < band){
902
            BandsFromStore additionalStore = this.additionalBands.get(storeCounter);
903
            if( (band-bandCounter) < additionalStore.size()){
904
                additionalStore.remove(band-bandCounter);
905
                if(additionalStore.size()==0){
906
                    DisposeUtils.disposeQuietly(additionalStore);
907
                    this.additionalBands.remove(additionalStore);
908
                }
909
                return;
910
            }
911
            bandCounter += additionalStore.size();
912
        }
913
    }
914

    
915
    private static class BandsFromStore extends AbstractDisposable{
916
        RasterStore store;
917
        List<Integer> bands;
918

    
919
        public BandsFromStore(RasterStore store){
920
            this.store = store;
921
            ToolsLocator.getDisposableManager().bind(store);
922
            this.bands = new ArrayList<>();
923
        }
924

    
925
        public BandsFromStore(RasterStore store, List<Integer> bands){
926
            this.store = store;
927
            ToolsLocator.getDisposableManager().bind(store);
928
            this.bands = bands;
929
        }
930

    
931
        /**
932
         * Add the band to the list
933
         *
934
         * @param band
935
         */
936
        public void add(int band){
937
            if(bands.contains(band)){
938
                throw new IllegalArgumentException("The band "+band+" is already added.");
939
            }
940
            this.bands.add(band);
941
        }
942

    
943
        /**
944
         * Remove the band from the list
945
         * @param band
946
         */
947
        public void remove(int band){
948
            if(!bands.contains(band)){
949
                throw new IllegalArgumentException("The band "+band+" isn't previously added.");
950
            }
951
            this.bands.remove(band);
952
        }
953

    
954
        public boolean contains(int band){
955
            return (bands.contains(band));
956
        }
957

    
958
        /**
959
         * Return the band from the store in the index position
960
         *
961
         * @param index
962
         * @return
963
         */
964
        public int get(int index){
965
            return this.bands.get(index);
966
        }
967

    
968
        public RasterStore getStore() {
969
            return store;
970
        }
971

    
972
        public int size() {
973
            return bands.size();
974
        }
975

    
976
        /**
977
         * Return the BandDescriptor of the band in the index position.
978
         * @param index
979
         * @return
980
         */
981
        public BandDescriptor getBandDescriptor(int index) {
982
            return store.getBandDescriptor(bands.get(index));
983
        }
984

    
985
        @Override
986
        protected void doDispose() throws BaseException {
987
            DisposeUtils.disposeQuietly(store);
988

    
989
        }
990

    
991
    }
992

    
993
    @Override
994
    public boolean isOwnBand(int band) {
995
        if(band < this.getProvider().getBands()){
996
            return true;
997
        }
998
        return false;
999
    }
1000

    
1001
    @Override
1002
    public DataStoreProviderFactory getProviderFactory() {
1003
        DataStoreProviderFactory factory = dataManager.getStoreProviderFactory(parameters.getDataStoreName());
1004
        return factory;
1005
    }
1006

    
1007
    @Override
1008
    public BufferDimensions getDimensions() throws InitializeException {
1009
        return this.getProvider().getDimensions();
1010
    }
1011

    
1012
    @Override
1013
    public boolean isTiled() {
1014
        return this.provider.isTiled();
1015
    }
1016

    
1017
    @Override
1018
    public boolean hasDynMethod(String name) {
1019
        return ((DynObject_v2)this.metadata).hasDynMethod(name);
1020
    }
1021

    
1022
    @Override
1023
    public StoresRepository getStoresRepository() {
1024
        final StoresRepository mainRepository = this.dataManager.getStoresRepository();
1025
        StoresRepository localRepository = this.provider.getStoresRepository();
1026
        if( localRepository==null ) {
1027
            return mainRepository;
1028
        }
1029
        StoresRepository repository = new BaseStoresRepository(this.getName());
1030
        repository.addRepository(localRepository);
1031
        repository.addRepository(mainRepository);
1032
        return repository;
1033
    }
1034

    
1035
    @Override
1036
    public ResourcesStorage getResourcesStorage() {
1037
        ResourcesStorage resourcesStorage;
1038
        try {
1039
            resourcesStorage = this.provider.getResourcesStorage();
1040
            if( resourcesStorage!=null ) {
1041
                return resourcesStorage;
1042
            }
1043
        } catch(Throwable th) {
1044
            
1045
        }
1046
        try {
1047
            DataServerExplorer explorer = this.getExplorer();
1048
            if( explorer==null ) {
1049
                return null;
1050
            }
1051
            return this.getExplorer().getResourcesStorage(this);
1052
        } catch (Exception ex) {
1053
            LOGGER.warn("Can't create resources storage",ex);
1054
            return null;
1055
        }
1056
    }
1057

    
1058
}