Statistics
| Revision:

svn-gvsig-desktop / branches / org.gvsig.desktop-2018a / 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 @ 43803

History | View | Annotate | Download (34.8 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.Iterator;
29
import java.util.List;
30
import java.util.Map;
31
import java.util.Map.Entry;
32
import java.util.Set;
33

    
34
import org.cresques.cts.IProjection;
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.exception.CloneException;
49
import org.gvsig.fmap.dal.exception.DataException;
50
import org.gvsig.fmap.dal.exception.InitializeException;
51
import org.gvsig.fmap.dal.exception.ProviderNotRegisteredException;
52
import org.gvsig.fmap.dal.exception.ValidateDataParametersException;
53
import org.gvsig.fmap.dal.feature.exception.PersistenceStoreAlreadyLoadedException;
54
import org.gvsig.fmap.dal.impl.DefaultDataManager;
55
import org.gvsig.fmap.dal.raster.RasterStoreProviderFactory;
56
import org.gvsig.fmap.dal.raster.api.BandAttributeDescriptor;
57
import org.gvsig.fmap.dal.raster.api.BandDescriptor;
58
import org.gvsig.fmap.dal.raster.api.BandQuery;
59
import org.gvsig.fmap.dal.raster.api.RasterCache;
60
import org.gvsig.fmap.dal.raster.api.RasterQuery;
61
import org.gvsig.fmap.dal.raster.api.RasterSet;
62
import org.gvsig.fmap.dal.raster.api.RasterStore;
63
import org.gvsig.fmap.dal.raster.api.RasterStoreNotification;
64
import org.gvsig.fmap.dal.raster.api.exceptions.RasterQueryCloneException;
65
import org.gvsig.fmap.dal.raster.impl.exceptions.AddingBandsException;
66
import org.gvsig.fmap.dal.raster.spi.RasterCacheStoreProvider;
67
import org.gvsig.fmap.dal.raster.spi.RasterStoreProvider;
68
import org.gvsig.fmap.dal.raster.spi.RasterStoreProviderServices;
69
import org.gvsig.fmap.dal.resource.Resource;
70
import org.gvsig.fmap.dal.resource.spi.ResourceProvider;
71
import org.gvsig.fmap.dal.spi.DALSPILocator;
72
import org.gvsig.fmap.dal.spi.DataManagerProviderServices;
73
import org.gvsig.fmap.dal.spi.DataStoreInitializer2;
74
import org.gvsig.fmap.geom.exception.CreateEnvelopeException;
75
import org.gvsig.fmap.geom.primitive.Envelope;
76
import org.gvsig.metadata.MetadataLocator;
77
import org.gvsig.metadata.MetadataManager;
78
import org.gvsig.metadata.exceptions.MetadataException;
79
import org.gvsig.raster.lib.buffer.api.Band;
80
import org.gvsig.raster.lib.buffer.api.Buffer;
81
import org.gvsig.raster.lib.buffer.api.BufferDimensions;
82
import org.gvsig.raster.lib.buffer.api.exceptions.BufferException;
83
import org.gvsig.timesupport.Interval;
84
import org.gvsig.tools.ToolsLocator;
85
import org.gvsig.tools.dispose.DisposeUtils;
86
import org.gvsig.tools.dispose.impl.AbstractDisposable;
87
import org.gvsig.tools.dynobject.DelegatedDynObject;
88
import org.gvsig.tools.dynobject.DynClass;
89
import org.gvsig.tools.dynobject.DynObject;
90
import org.gvsig.tools.dynobject.DynObjectManager;
91
import org.gvsig.tools.dynobject.DynObject_v2;
92
import org.gvsig.tools.dynobject.DynStruct;
93
import org.gvsig.tools.dynobject.exception.DynFieldNotFoundException;
94
import org.gvsig.tools.dynobject.exception.DynMethodException;
95
import org.gvsig.tools.exception.BaseException;
96
import org.gvsig.tools.locator.LocatorException;
97
import org.gvsig.tools.observer.Observable;
98
import org.gvsig.tools.observer.Observer;
99
import org.gvsig.tools.observer.impl.DelegateWeakReferencingObservable;
100
import org.gvsig.tools.persistence.PersistenceManager;
101
import org.gvsig.tools.persistence.PersistentState;
102
import org.gvsig.tools.persistence.exception.PersistenceException;
103
import org.gvsig.tools.visitor.Visitor;
104

    
105
/**
106
 * Implements RasterStore
107
 *
108
 * @author dmartinezizquierdo
109
 *
110
 */
111
public class DefaultRasterStore extends AbstractDisposable implements DataStoreInitializer2,
112
    RasterStoreProviderServices, RasterStore, Observer {
113

    
114
    private static final Logger LOG = LoggerFactory.getLogger(DefaultRasterStore.class);
115

    
116
    private static final String PERSISTENCE_DEFINITION_NAME = "RasterStore";
117
    private static final String METADATA_DEFINITION_NAME = "RasterStore";
118

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

    
125
    private DelegateWeakReferencingObservable delegateObservable = new DelegateWeakReferencingObservable(this);
126

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

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

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

    
156
    /**
157
     * @return dataManager
158
     */
159
    public DataManager getManager() {
160
        return this.dataManager;
161
    }
162

    
163
    @Override
164
    public String getName() {
165
        return this.provider.getName();
166
    }
167

    
168
    @Override
169
    public String getFullName() {
170
        return this.provider.getFullName();
171
    }
172

    
173
    @Override
174
    public DataStoreParameters getParameters() {
175
        return parameters;
176
    }
177

    
178
    @Override
179
    public String getProviderName() {
180
        return this.provider.getProviderName();
181
    }
182

    
183
    @Override
184
    public void refresh() throws DataException {
185
        this.notifyChange(RasterStoreNotification.BEFORE_REFRESH);
186
        this.provider.refresh();
187
        this.notifyChange(RasterStoreNotification.AFTER_REFRESH);
188
    }
189

    
190
    @Override
191
    public DataSet getDataSet() throws DataException {
192
        return this.getRasterSet();
193
    }
194

    
195
    @Override
196
    public DataSet getDataSet(DataQuery dataQuery) throws DataException {
197
        return this.getRasterSet((RasterQuery) dataQuery);
198
    }
199

    
200
    @Override
201
    public void getDataSet(Observer observer) throws DataException {
202
        this.getRasterSet(null, observer);
203
    }
204

    
205
    @Override
206
    public void getDataSet(DataQuery dataQuery, Observer observer) throws DataException {
207
        this.getRasterSet((RasterQuery) dataQuery, observer);
208
    }
209

    
210
    @Override
211
    public RasterSet getRasterSet(RasterQuery rasterQuery) throws DataException {
212

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

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

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

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

    
298
    @Override
299
    public RasterSet getRasterSet() throws DataException {
300
        return getRasterSet(createRasterQuery());
301
    }
302

    
303
    /**
304
     * Adds an observer to the DataSet
305
     *
306
     * @param observer
307
     * @throws DataException
308
     */
309
    public void getRasterSet(Observer observer) throws DataException {
310
        RasterSet set = this.getRasterSet();
311
        set.addObserver(observer);
312
    }
313

    
314
    /**
315
     * Adds an observer to the queried DataSet
316
     *
317
     * @param rasterQuery
318
     * @param observer
319
     * @throws DataException
320
     */
321
    public void getRasterSet(RasterQuery rasterQuery, Observer observer) throws DataException {
322
        RasterSet set = this.getRasterSet(rasterQuery);
323
        set.addObserver(observer);
324
    }
325

    
326
    @Override
327
    public void accept(Visitor visitor) throws BaseException {
328
        RasterSet set = getRasterSet();
329
        try {
330
            set.accept(visitor);
331
        } finally {
332
            set.dispose();
333
        }
334
    }
335

    
336
    @Override
337
    public void accept(Visitor visitor, DataQuery dataQuery) throws BaseException {
338
        RasterSet set = getRasterSet((RasterQuery) dataQuery);
339
        try {
340
            set.accept(visitor);
341
        } finally {
342
            set.dispose();
343
        }
344

    
345
    }
346

    
347
    @Override
348
    public DataSet getSelection() throws DataException {
349
        // TODO Auto-generated method stub
350
        return null;
351
    }
352

    
353
    @Override
354
    public void setSelection(DataSet selection) throws DataException {
355
        // TODO Auto-generated method stub
356

    
357
    }
358

    
359
    @Override
360
    public DataSet createSelection() throws DataException {
361
        // TODO Auto-generated method stub
362
        return null;
363
    }
364

    
365
    @Override
366
    public Iterator<?> getChildren() {
367
        return this.provider.getChilds();
368
    }
369

    
370
    @Override
371
    public DataServerExplorer getExplorer() throws DataException, ValidateDataParametersException {
372
        return this.provider.getExplorer();
373
    }
374

    
375
    @Override
376
    public DataQuery createQuery() {
377
        return createRasterQuery();
378
    }
379

    
380
    @Override
381
    public Interval getInterval() {
382
        return this.provider.getInterval();
383
    }
384

    
385
    @Override
386
    public Collection<?> getTimes() {
387
        return this.provider.getTimes();
388
    }
389

    
390
    @Override
391
    public Collection<?> getTimes(Interval interval) {
392
        return this.provider.getTimes(interval);
393
    }
394

    
395
    @Override
396
    public void disableNotifications() {
397
        this.delegateObservable.disableNotifications();
398
    }
399

    
400
    @Override
401
    public void enableNotifications() {
402
        this.delegateObservable.enableNotifications();
403

    
404
    }
405

    
406
    @Override
407
    public void beginComplexNotification() {
408
        this.delegateObservable.beginComplexNotification();
409

    
410
    }
411

    
412
    @Override
413
    public void endComplexNotification() {
414
        this.delegateObservable.endComplexNotification();
415
    }
416

    
417
    @Override
418
    public void addObserver(Observer observer) {
419
        if (delegateObservable != null) {
420
            this.delegateObservable.addObserver(observer);
421
        }
422
    }
423

    
424
    @Override
425
    public void deleteObserver(Observer observer) {
426
        if (delegateObservable != null) {
427
            this.delegateObservable.deleteObserver(observer);
428
        }
429

    
430
    }
431

    
432
    @Override
433
    public void deleteObservers() {
434
        this.delegateObservable.deleteObservers();
435
    }
436

    
437
    @Override
438
    public void saveToState(PersistentState state) throws PersistenceException {
439

    
440
        state.set("dataStoreName", this.getName());
441
        state.set("parameters", this.parameters);
442
    }
443

    
444
    @Override
445
    public void loadFromState(PersistentState state) throws PersistenceException {
446
        if (this.provider != null) {
447
            throw new PersistenceStoreAlreadyLoadedException(this.getName());
448
        }
449
        if (this.getManager() == null) {
450
            this.dataManager = (DefaultDataManager) DALLocator.getDataManager();
451
        }
452

    
453
        DataStoreParameters params = (DataStoreParameters) state.get("parameters");
454

    
455
        try {
456

    
457
            this.intialize(this.dataManager, params);
458
            this.setProvider(this.provider);
459

    
460
        } catch (InitializeException e) {
461
            throw new PersistenceException(e);
462
        } catch (DataException e) {
463
            throw new PersistenceException(e);
464
        }
465

    
466
    }
467

    
468
    //
469
    // ====================================================================
470
    // Metadata related methods
471
    //
472

    
473
    @Override
474
    public Set<?> getMetadataChildren() throws MetadataException {
475
        // TODO Auto-generated method stub
476
        return null;
477
    }
478

    
479
    @Override
480
    public Object getMetadataID() throws MetadataException {
481
        return this.provider.getSourceId();
482
    }
483

    
484
    @Override
485
    public String getMetadataName() throws MetadataException {
486
        return this.provider.getProviderName();
487
    }
488

    
489
    @Override
490
    public DynClass getDynClass() {
491
        return this.metadata.getDynClass();
492
    }
493

    
494
    @Override
495
    public void implement(DynClass dynClass) {
496
        this.metadata.implement(dynClass);
497
    }
498

    
499
    @Override
500
    public void delegate(DynObject dynObject) {
501
        this.metadata.delegate(dynObject);
502
    }
503

    
504
    @Override
505
    public Object getDynValue(String name) throws DynFieldNotFoundException {
506
        if (this.metadata.hasDynValue(name)) {
507
            return this.metadata.getDynValue(name);
508
        }
509
        if (METADATA_PROVIDER.equalsIgnoreCase(name)) {
510
            return this.provider.getProviderName();
511
        } else if (METADATA_CONTAINERNAME.equalsIgnoreCase(name)) {
512
            return this.provider.getSourceId();
513
        }
514
        return this.metadata.getDynValue(name);
515
    }
516

    
517
    @Override
518
    public void setDynValue(String name, Object value) throws DynFieldNotFoundException {
519

    
520
        this.metadata.setDynValue(name, value);
521

    
522
    }
523

    
524
    @Override
525
    public boolean hasDynValue(String name) {
526
        return this.metadata.hasDynValue(name);
527
    }
528

    
529
    @Override
530
    public Object invokeDynMethod(String name, Object[] args) throws DynMethodException {
531
        return this.metadata.invokeDynMethod(this, name, args);
532
    }
533

    
534
    @Override
535
    public Object invokeDynMethod(int code, Object[] args) throws DynMethodException {
536
        return this.metadata.invokeDynMethod(this, code, args);
537
    }
538

    
539
    @Override
540
    public void clear() {
541
        if (metadata != null) {
542
            metadata.clear();
543
        }
544
    }
545

    
546
    @Override
547
    public RasterQuery createRasterQuery() {
548
        return new DefaultRasterQuery();
549
    }
550

    
551
    @Override
552
    public DataStore getStore() {
553
        return this;
554
    }
555

    
556
    @Override
557
    public void update(Observable observable, Object notification) {
558
        if (observable instanceof DataSet) {
559
            this.notifyChange(RasterStoreNotification.DATASET_CHANGED);
560

    
561
        } else {
562
            if (observable instanceof RasterStoreProvider) {
563
                if (observable == this.provider) {
564
                    this.notifyChange(RasterStoreNotification.STORE_PROVIDER_CHANGED);
565
                }
566
            }
567
        }
568
    }
569

    
570
    @Override
571
    protected void doDispose() throws BaseException {
572

    
573
        LOG.debug("Dispose DefaultRasterStore '"+this.getFullName()+"'");
574

    
575
        this.notifyChange(DataStoreNotification.BEFORE_DISPOSE);
576
        DisposeUtils.dispose(this.provider);
577
        this.provider = null;
578
        this.parameters = null;
579
        if(additionalBands!=null){
580
            for (Iterator<BandsFromStore> iterator = additionalBands.iterator(); iterator.hasNext();) {
581
                BandsFromStore bandsFromStore = (BandsFromStore) iterator.next();
582
                DisposeUtils.dispose(bandsFromStore);
583
            }
584
            this.additionalBands = null;
585
        }
586

    
587
        this.notifyChange(DataStoreNotification.AFTER_DISPOSE);
588
        if (delegateObservable != null) {
589
            this.delegateObservable.deleteObservers();
590
            this.delegateObservable = null;
591
        }
592
    }
593

    
594
    @Override
595
    public Object clone() throws CloneNotSupportedException {
596
        DataStoreParameters dsp = getParameters();
597

    
598
        DefaultRasterStore cloned_store = null;
599

    
600
        try {
601
            cloned_store = (DefaultRasterStore) DALLocator.getDataManager().openStore(this.getProviderName(), dsp);
602
            cloned_store.additionalBands = new ArrayList<DefaultRasterStore.BandsFromStore>(additionalBands);
603
        } catch (Exception e) {
604
            throw new CloneException(e);
605
        }
606
        return cloned_store;
607

    
608
    }
609

    
610
    /**
611
     * Notifies change
612
     *
613
     * @param notification
614
     */
615
    public void notifyChange(String notification) {
616
        if (delegateObservable != null) {
617
            notifyChange(new DefaultRasterStoreNotification(this, notification));
618
        }
619

    
620
    }
621

    
622
    @Override
623
    public void notifyChange(String notification, ResourceProvider data) {
624
        notifyChange(new DefaultRasterStoreNotification(this, DataStoreNotification.RESOURCE_CHANGED));
625
    }
626

    
627
    /**
628
     * Notifies change
629
     *
630
     * @param storeNotification
631
     */
632
    public void notifyChange(DefaultRasterStoreNotification storeNotification) {
633
        try {
634
            delegateObservable.notifyObservers(storeNotification);
635
        } catch (Exception e) {
636
            LOG.warn("Problems notifying changes in store '"+getName()+"'.", e);
637
        }
638
    }
639

    
640
    /**
641
     * Gets this provider
642
     *
643
     * @return RasterStoreProvider
644
     */
645
    public RasterStoreProvider getProvider() {
646
        return this.provider;
647
    }
648

    
649
    @Override
650
    public Envelope getEnvelope() throws DataException, LocatorException, CreateEnvelopeException {
651
        return getDimensions().getEnvelope();
652
    }
653

    
654
//    @Override
655
//    public BandInfo getBandInfo(int band) {
656
//        int bands = this.provider.getBands();
657
//        if(band<bands){
658
//            return this.provider.getBandInfo(band);
659
//        }
660
//
661
//        if(additionalBands!=null){
662
//            for (BandsFromStore bandsFromStore : additionalBands) {
663
//                if((band-bands)<bandsFromStore.bands.size()){
664
//                    RasterStore store = bandsFromStore.getStore();
665
//                    int storeBand = bandsFromStore.get(band-bands);
666
//                    return store.getBandInfo(storeBand);
667
//                }
668
//                bands+=bandsFromStore.size();
669
//            }
670
//        }
671
//        return null;
672
//    }
673

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

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

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

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

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

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

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

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

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

    
736
    @Override
737
    public RasterStore getRasterStore() {
738
        return this;
739
    }
740

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

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

    
751
        DataManagerProviderServices manager = DALSPILocator.getDataManagerProviderServices();
752
        RasterStoreProviderFactory providerFactory =
753
            (RasterStoreProviderFactory) manager.getStoreProviderFactory(providerName);
754

    
755
        if (providerFactory == null) {
756
            throw new ProviderNotRegisteredException(providerName);
757
        }
758

    
759
        RasterCacheStoreProvider cache =
760
            (RasterCacheStoreProvider) providerFactory.createProvider((DataParameters) parameters, this);
761

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

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

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

    
779
        DynObjectManager dynManager = ToolsLocator.getDynObjectManager();
780

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

    
785
        this.dataManager = (DefaultDataManager) dataManager;
786

    
787
        this.parameters = parameters;
788

    
789
    }
790

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

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

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

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

    
823
        if(additionalBands==null){
824
            this.additionalBands = new ArrayList<BandsFromStore>();
825
        }
826

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

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

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

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

    
868
        if(additionalBands==null){
869
            this.additionalBands = new ArrayList<BandsFromStore>();
870
        }
871

    
872
        boolean found = false;
873
        for (BandsFromStore bandsFromStore : additionalBands) {
874
            if(bandsFromStore.getStore().equals(store)){
875
                found = true;
876
                for (Iterator<Integer> bandIterator = bands.iterator(); bandIterator.hasNext();) {
877
                    Integer band = (Integer) bandIterator.next();
878
                    bandsFromStore.add(band);
879
                }
880
            }
881
        }
882
        if(!found){
883
            BandsFromStore bandsFromStore = new BandsFromStore(store, bands);
884
            this.additionalBands.add(bandsFromStore);
885
        }
886
    }
887

    
888
    public void clearAdditionalBands() {
889
        if (this.additionalBands != null) {
890
            for (BandsFromStore bandsFromStore : additionalBands) {
891
                DisposeUtils.dispose(bandsFromStore);
892
            }
893
        }
894
        this.additionalBands = null;
895
    }
896

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

    
918
    private static class BandsFromStore extends AbstractDisposable{
919
        RasterStore store;
920
        List<Integer> bands;
921

    
922
        public BandsFromStore(RasterStore store){
923
            this.store = store;
924
            ToolsLocator.getDisposableManager().bind(store);
925
            this.bands = new ArrayList<Integer>();
926
        }
927

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

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

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

    
957
        public boolean contains(int band){
958
            return (bands.contains(band));
959
        }
960

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

    
971
        public RasterStore getStore() {
972
            return store;
973
        }
974

    
975
        public int size() {
976
            return bands.size();
977
        }
978

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

    
988
        @Override
989
        protected void doDispose() throws BaseException {
990
            DisposeUtils.disposeQuietly(store);
991

    
992
        }
993

    
994
    }
995

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

    
1004
    public DataStoreProviderFactory getProviderFactory() {
1005
        DataStoreProviderFactory factory = dataManager.getStoreProviderFactory(parameters.getDataStoreName());
1006
        return factory;
1007
    }
1008

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

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

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