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

History | View | Annotate | Download (34.3 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.BandAttributeDescriptor;
57
import org.gvsig.fmap.dal.raster.BandDescriptor;
58
import org.gvsig.fmap.dal.raster.BandQuery;
59
import org.gvsig.fmap.dal.raster.RasterCache;
60
import org.gvsig.fmap.dal.raster.RasterQuery;
61
import org.gvsig.fmap.dal.raster.RasterSet;
62
import org.gvsig.fmap.dal.raster.RasterStore;
63
import org.gvsig.fmap.dal.raster.RasterStoreNotification;
64
import org.gvsig.fmap.dal.raster.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 List<BandDescriptor> getBandDescriptors() {
656
        List<BandDescriptor> bands = new ArrayList<>();
657
        for( int i=0; i<this.getBands(); i++ ) {
658
            bands.add(this.getBandDescriptor(i));
659
        }
660
        return bands;
661
    }
662

    
663
    @Override
664
    public BandDescriptor getBandDescriptor(int band) {
665
        int bandsCounter = this.provider.getBands();
666
        if(band<bandsCounter){
667
            return this.provider.getBandDescriptor(band);
668
        }
669

    
670
        if(additionalBands!=null){
671
            for (BandsFromStore bandsFromStore : additionalBands) {
672
                if((band-bandsCounter)<bandsFromStore.bands.size()){
673
                    return bandsFromStore.getBandDescriptor(band-bandsCounter);
674
                }
675
                bandsCounter+=bandsFromStore.size();
676
            }
677
        }
678
        return null;
679
    }
680

    
681
    @Override
682
    public BandQuery createBandQuery(int band) {
683
        return new DefaultBandQuery(band, getBandDescriptor(band));
684
    }
685

    
686
    @Override
687
    public int getBands() {
688
        int bands = this.provider.getBands();
689
        if(additionalBands!=null){
690
            for (BandsFromStore bandsFromStore : additionalBands) {
691
                bands+=bandsFromStore.size();
692
            }
693
        }
694
        return bands;
695
    }
696

    
697
    @Override
698
    public BandDescriptor createBandDescriptor(int band, List<BandAttributeDescriptor> attributes) {
699
        return new DefaultBandDescriptor(this, band, attributes);
700
    }
701

    
702
    @Override
703
    public BandAttributeDescriptor createBandAttributeDescriptor(int band, String name, String description,
704
        List<Object> values, String units) {
705
        return new DefaultBandAttributeDescriptor(band, name, description, values, units);
706
    }
707

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

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

    
720
    @Override
721
    public void notifyChange(String notification, Resource resource) {
722
        notifyChange(new DefaultRasterStoreNotification(this, DataStoreNotification.RESOURCE_CHANGED));
723
    }
724

    
725
    @Override
726
    public RasterStore getRasterStore() {
727
        return this;
728
    }
729

    
730
    @Override
731
    public void useCache(String providerName, DynObject parameters) throws DataException {
732

    
733
        if (providerName == null) {
734
            throw new InitializeException("It is necessary to provide a cache name", null);
735
        }
736
        if (parameters == null) {
737
            throw new InitializeException("It is necessary to provide parameters to create the explorer", null);
738
        }
739

    
740
        DataManagerProviderServices manager = DALSPILocator.getDataManagerProviderServices();
741
        RasterStoreProviderFactory providerFactory =
742
            (RasterStoreProviderFactory) manager.getStoreProviderFactory(providerName);
743

    
744
        if (providerFactory == null) {
745
            throw new ProviderNotRegisteredException(providerName);
746
        }
747

    
748
        RasterCacheStoreProvider cache =
749
            (RasterCacheStoreProvider) providerFactory.createProvider((DataParameters) parameters, this);
750

    
751
        RasterQuery rasterQuery = this.createRasterQuery();
752
        cache.apply(provider,
753
            (IProjection) this.getParameters().getDynValue(DataStore.METADATA_CRS), rasterQuery);
754
        this.provider = cache;
755
    }
756

    
757
    @Override
758
    public RasterCache getCache() {
759
        if(this.provider instanceof RasterCache){
760
            return (RasterCache) this.provider;
761
        }
762
        return null;
763
    }
764

    
765
    @Override
766
    public void intialize(DataManager dataManager, DataStoreParameters parameters) throws InitializeException {
767

    
768
        DynObjectManager dynManager = ToolsLocator.getDynObjectManager();
769

    
770
        this.metadata =
771
            (DelegatedDynObject) dynManager.createDynObject(METADATA_DEFINITION_NAME,
772
                MetadataManager.METADATA_NAMESPACE);
773

    
774
        this.dataManager = (DefaultDataManager) dataManager;
775

    
776
        this.parameters = parameters;
777

    
778
    }
779

    
780
    @Override
781
    public void setProvider(org.gvsig.fmap.dal.DataStoreProvider provider) {
782
        if(this.provider != null){
783
            throw new IllegalStateException("Provider already set.");
784
        }
785
        this.provider = (RasterStoreProvider) provider;
786
        // FIXME: habr?a que hacer un bind del provider y a?adir un dispose en el openStore del DataManager
787
//        DisposeUtils.bind(this.provider);
788
        this.delegate(this.provider);
789
    }
790

    
791
    @Override
792
    public void addBand(RasterStore store, int band) throws DataException {
793
        if(store.equals(this)){
794
            LOG.warn("Can't add bands that belong to this same store.");
795
            throw new IllegalArgumentException("Can't add bands that belong to this same store.");
796
        }
797

    
798
        try {
799
            if(!store.getEnvelope().equals(this.getEnvelope())){
800
                LOG.warn("The envelopes are differents.");
801
                throw new AddingBandsException(store.getName(), this.getName(), "The envelopes are differents.", null);
802
            }
803
        } catch (LocatorException | DataException | CreateEnvelopeException e) {
804
            LOG.warn("Can't compare the envelopes.",e);
805
            throw new AddingBandsException(store.getName(), this.getName(), "Can't compare the envelopes.", e);
806
        }
807

    
808
        if(!store.getParameters().getDynValue(METADATA_CRS).equals(this.getParameters().getDynValue(METADATA_CRS))){
809
            throw new AddingBandsException(store.getName(), this.getName(), "The projections are differents.", null);
810
        }
811

    
812
        if(additionalBands==null){
813
            this.additionalBands = new ArrayList<BandsFromStore>();
814
        }
815

    
816
        boolean found = false;
817
        for (Iterator<BandsFromStore> iterator = additionalBands.iterator(); iterator.hasNext();) {
818
            BandsFromStore bandsFromStore = (BandsFromStore) iterator.next();
819
            if(bandsFromStore.getStore().equals(store)){
820
                found = true;
821
                if(bandsFromStore.contains(band)){
822
                    LOG.warn("The band '"+band+"' of the store '"+store.getName()+"' is already added to the additional bands.");
823
                } else {
824
                    bandsFromStore.add(band);
825
                }
826
                break;
827
            }
828
        }
829
        if(!found){
830
            BandsFromStore bandsFromStore = new BandsFromStore(store);
831
            bandsFromStore.add(band);
832
            this.additionalBands.add(bandsFromStore);
833
        }
834
    }
835

    
836
    @Override
837
    public void addBands(RasterStore store, List<Integer> bands) throws DataException {
838
        if(store.equals(this)){
839
            LOG.warn("Can't add bands that belong to this same store.");
840
            throw new IllegalArgumentException("Can't add bands that belong to this same store.");
841
        }
842

    
843
        try {
844
            if(!store.getEnvelope().equals(this.getEnvelope())){
845
                LOG.warn("The envelopes are differents.");
846
                throw new AddingBandsException(store.getName(), this.getName(), "The envelopes are differents.", null);
847
            }
848
        } catch (LocatorException | DataException | CreateEnvelopeException e) {
849
            LOG.warn("Can't compare the envelopes.",e);
850
            throw new AddingBandsException(store.getName(), this.getName(), "Can't compare the envelopes.", e);
851
        }
852

    
853
        if(!store.getParameters().getDynValue(METADATA_CRS).equals(this.getParameters().getDynValue(METADATA_CRS))){
854
            throw new AddingBandsException(store.getName(), this.getName(), "The projections are differents.", null);
855
        }
856

    
857
        if(additionalBands==null){
858
            this.additionalBands = new ArrayList<BandsFromStore>();
859
        }
860

    
861
        boolean found = false;
862
        for (BandsFromStore bandsFromStore : additionalBands) {
863
            if(bandsFromStore.getStore().equals(store)){
864
                found = true;
865
                for (Iterator<Integer> bandIterator = bands.iterator(); bandIterator.hasNext();) {
866
                    Integer band = (Integer) bandIterator.next();
867
                    bandsFromStore.add(band);
868
                }
869
            }
870
        }
871
        if(!found){
872
            BandsFromStore bandsFromStore = new BandsFromStore(store, bands);
873
            this.additionalBands.add(bandsFromStore);
874
        }
875
    }
876

    
877
    public void clearAdditionalBands() {
878
        if (this.additionalBands != null) {
879
            for (BandsFromStore bandsFromStore : additionalBands) {
880
                DisposeUtils.dispose(bandsFromStore);
881
            }
882
        }
883
        this.additionalBands = null;
884
    }
885

    
886
    @Override
887
    public void removeBand(int band) {
888
        if(band<getProvider().getBands()){
889
            throw new IllegalArgumentException("Can't remove bands of main store.");
890
        }
891
        int bandCounter = getProvider().getBands();
892
        int storeCounter = 0;
893
        while(bandCounter < band){
894
            BandsFromStore additionalStore = this.additionalBands.get(storeCounter);
895
            if( (band-bandCounter) < additionalStore.size()){
896
                additionalStore.remove(band-bandCounter);
897
                if(additionalStore.size()==0){
898
                    DisposeUtils.disposeQuietly(additionalStore);
899
                    this.additionalBands.remove(additionalStore);
900
                }
901
                return;
902
            }
903
            bandCounter += additionalStore.size();
904
        }
905
    }
906

    
907
    private static class BandsFromStore extends AbstractDisposable{
908
        RasterStore store;
909
        List<Integer> bands;
910

    
911
        public BandsFromStore(RasterStore store){
912
            this.store = store;
913
            ToolsLocator.getDisposableManager().bind(store);
914
            this.bands = new ArrayList<Integer>();
915
        }
916

    
917
        public BandsFromStore(RasterStore store, List<Integer> bands){
918
            this.store = store;
919
            ToolsLocator.getDisposableManager().bind(store);
920
            this.bands = bands;
921
        }
922

    
923
        /**
924
         * Add the band to the list
925
         *
926
         * @param band
927
         */
928
        public void add(int band){
929
            if(bands.contains(band)){
930
                throw new IllegalArgumentException("The band "+band+" is already added.");
931
            }
932
            this.bands.add(band);
933
        }
934

    
935
        /**
936
         * Remove the band from the list
937
         * @param band
938
         */
939
        public void remove(int band){
940
            if(!bands.contains(band)){
941
                throw new IllegalArgumentException("The band "+band+" isn't previously added.");
942
            }
943
            this.bands.remove(band);
944
        }
945

    
946
        public boolean contains(int band){
947
            return (bands.contains(band));
948
        }
949

    
950
        /**
951
         * Return the band from the store in the index position
952
         *
953
         * @param index
954
         * @return
955
         */
956
        public int get(int index){
957
            return this.bands.get(index).intValue();
958
        }
959

    
960
        public RasterStore getStore() {
961
            return store;
962
        }
963

    
964
        public int size() {
965
            return bands.size();
966
        }
967

    
968
        /**
969
         * Return the BandDescriptor of the band in the index position.
970
         * @param index
971
         * @return
972
         */
973
        public BandDescriptor getBandDescriptor(int index) {
974
            return store.getBandDescriptor(bands.get(index));
975
        }
976

    
977
        @Override
978
        protected void doDispose() throws BaseException {
979
            DisposeUtils.disposeQuietly(store);
980

    
981
        }
982

    
983
    }
984

    
985
    @Override
986
    public boolean isOwnBand(int band) {
987
        if(band < this.getProvider().getBands()){
988
            return true;
989
        }
990
        return false;
991
    }
992

    
993
    public DataStoreProviderFactory getProviderFactory() {
994
        DataStoreProviderFactory factory = dataManager.getStoreProviderFactory(parameters.getDataStoreName());
995
        return factory;
996
    }
997

    
998
    @Override
999
    public BufferDimensions getDimensions() throws InitializeException {
1000
        return this.getProvider().getDimensions();
1001
    }
1002

    
1003
    @Override
1004
    public boolean isTiled() {
1005
        return this.provider.isTiled();
1006
    }
1007

    
1008
    @Override
1009
    public boolean hasDynMethod(String name) {
1010
        return ((DynObject_v2)this.metadata).hasDynMethod(name);
1011
    }
1012
}