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 / feature / paging / impl / FeaturePagingHelperImpl.java @ 43726

History | View | Annotate | Download (28 KB)

1 40559 jjdelcerro
/**
2
 * gvSIG. Desktop Geographic Information System.
3 40435 jjdelcerro
 *
4 40559 jjdelcerro
 * Copyright (C) 2007-2013 gvSIG Association.
5 40435 jjdelcerro
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8 40559 jjdelcerro
 * as published by the Free Software Foundation; either version 3
9 40435 jjdelcerro
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21 40559 jjdelcerro
 * For any additional information, do not hesitate to contact us
22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
23 40435 jjdelcerro
 */
24
package org.gvsig.fmap.dal.feature.paging.impl;
25
26 43660 jjdelcerro
import java.util.ArrayList;
27 41212 jjdelcerro
import java.util.Collection;
28 43660 jjdelcerro
import java.util.Date;
29 41212 jjdelcerro
import java.util.Iterator;
30
import java.util.List;
31
import java.util.ListIterator;
32 40435 jjdelcerro
import org.slf4j.Logger;
33
import org.slf4j.LoggerFactory;
34
35
import org.gvsig.fmap.dal.exception.DataException;
36
import org.gvsig.fmap.dal.feature.EditableFeature;
37
import org.gvsig.fmap.dal.feature.Feature;
38
import org.gvsig.fmap.dal.feature.FeatureQuery;
39
import org.gvsig.fmap.dal.feature.FeatureSelection;
40
import org.gvsig.fmap.dal.feature.FeatureSet;
41
import org.gvsig.fmap.dal.feature.FeatureStore;
42
import org.gvsig.fmap.dal.feature.FeatureType;
43 41819 fdiaz
import org.gvsig.fmap.dal.feature.exception.ConcurrentDataModificationException;
44 40435 jjdelcerro
import org.gvsig.fmap.dal.feature.exception.FeatureIndexException;
45 42775 jjdelcerro
import org.gvsig.fmap.dal.feature.impl.dynobjectutils.DynObjectFeatureFacade;
46
import org.gvsig.fmap.dal.feature.paging.FacadeOfAFeaturePagingHelper;
47 40435 jjdelcerro
import org.gvsig.fmap.dal.feature.paging.FeaturePagingHelper;
48
import org.gvsig.tools.dynobject.DynObject;
49
import org.gvsig.tools.dynobject.DynObjectSet;
50
import org.gvsig.tools.dynobject.impl.DefaultDynObjectPagingHelper;
51
import org.gvsig.tools.exception.BaseException;
52
import org.gvsig.tools.visitor.VisitCanceledException;
53
import org.gvsig.tools.visitor.Visitor;
54
55
/**
56
 * Helper class to access the values of a FeatureCollection by position. Handles
57
 * pagination automatically to avoid filling the memory in case of big
58
 * collections.
59 41819 fdiaz
 *
60 40435 jjdelcerro
 * TODO: evaluate if its more convenient to read values in the background when
61
 * the returned value is near the end of the page, instead of loading a page on
62
 * demand.
63 41819 fdiaz
 *
64 40435 jjdelcerro
 * @author gvSIG Team
65
 */
66
public class FeaturePagingHelperImpl extends DefaultDynObjectPagingHelper
67
    implements FeaturePagingHelper {
68
69 43660 jjdelcerro
    private static final Logger LOG = LoggerFactory.getLogger(FeaturePagingHelperImpl.class);
70 40435 jjdelcerro
71 43660 jjdelcerro
    private static class Page {
72
73 43691 jjdelcerro
        private Feature[] features;
74 43660 jjdelcerro
        private final long number;
75
        private final int size;
76
        private long lastaccess;
77
78
        public Page(long number, int size) {
79
            this.size = size;
80
            this.number = number;
81
            this.features = new Feature[size];
82
            this.lastaccess = 0;
83
        }
84
85
        public void setFeature(int i, Feature copy) {
86
            this.features[i] = copy;
87
        }
88
89
        public Feature[] getFeatures() {
90
            this.lastaccess = (new Date()).getTime();
91
            return this.features;
92
        }
93
94
        public long getPageNumber() {
95
            return this.number;
96
        }
97
98
        public long getLastAccess() {
99
            return this.lastaccess;
100
        }
101
102
        public int size() {
103
            return this.size;
104
        }
105 43691 jjdelcerro
106
        public void dispose() {
107
            for (int i = 0; i < features.length; i++) {
108
                features[i] = null;
109
            }
110
            this.features = null;
111
            this.lastaccess = 0;
112
        }
113 43660 jjdelcerro
    }
114
115
    private static class PageCache {
116
117
        private final int maxpages;
118 43691 jjdelcerro
        private List<Page> pages;
119 43660 jjdelcerro
120
        public PageCache(int maxpages) {
121
            this.maxpages = maxpages;
122
            this.pages = new ArrayList<>();
123
        }
124
125 43691 jjdelcerro
        public void clear() {
126
            for (Page page : pages) {
127
                page.dispose();
128
            }
129
            this.pages = new ArrayList<>();
130
        }
131
132 43660 jjdelcerro
        public Page get(long pageNumber) {
133
            for( Page page : pages ) {
134
                if( page.getPageNumber() == pageNumber ) {
135
                    return page;
136
                }
137
            }
138
            return null;
139
        }
140
141
        public void add(Page page) {
142
            if( this.pages.size()< this.maxpages ) {
143
                this.pages.add(page);
144
                return;
145
            }
146
            int toDrop = 0;
147
            for( int i=0; i<this.pages.size(); i++ ) {
148
                if( this.pages.get(i).getLastAccess()<this.pages.get(toDrop).getLastAccess() ) {
149
                    toDrop = i;
150
                }
151
            }
152
            this.pages.set(toDrop, page);
153
        }
154
    }
155
156 40435 jjdelcerro
    private FeatureQuery query;
157
158
    private FeatureStore featureStore;
159
160
    /** If the selected Features must be returned as the first ones. **/
161
    private boolean selectionUp = false;
162
163
    private FeatureSet featSet = null;
164
    private FeatureSelection initialSelection = null;
165
166
    private Feature[] features = null;
167 43660 jjdelcerro
    private PageCache cachedPages = null;
168 40435 jjdelcerro
169 41212 jjdelcerro
    private boolean initialization_completed = false;
170 42807 jjdelcerro
171
    private FeatureSelection selection = null;
172 40435 jjdelcerro
    /**
173
     * Constructs a FeaturePagingHelperImpl from data of a FeatureStore.
174 41819 fdiaz
     *
175 40435 jjdelcerro
     * @param featureStore
176
     *            to extract data from
177
     * @throws DataException
178
     *             if there is an error initializing the helper
179
     */
180
    public FeaturePagingHelperImpl(FeatureStore featureStore)
181
        throws BaseException {
182
        this(featureStore, DEFAULT_PAGE_SIZE);
183
    }
184
185
    /**
186
     * Constructs a FeaturePagingHelperImpl from data of a FeatureStore.
187 41819 fdiaz
     *
188 40435 jjdelcerro
     * @param featureStore
189
     *            to extract data from
190
     * @param pageSize
191
     *            the number of elements per page data
192
     * @throws DataException
193
     *             if there is an error initializing the helper
194
     */
195
    public FeaturePagingHelperImpl(FeatureStore featureStore, int pageSize)
196
        throws BaseException {
197
        this(featureStore, null, pageSize);
198
    }
199
200
    /**
201
     * Constructs a FeaturePagingHelperImpl from data of a FeatureStore.
202 41819 fdiaz
     *
203 40435 jjdelcerro
     * @param featureStore
204
     *            to extract data from
205
     * @throws DataException
206
     *             if there is an error initializing the helper
207
     */
208
    public FeaturePagingHelperImpl(FeatureStore featureStore,
209
        FeatureQuery featureQuery) throws BaseException {
210
        this(featureStore, featureQuery, DEFAULT_PAGE_SIZE);
211
    }
212
213
    /**
214
     * Constructs a FeaturePagingHelperImpl from data of a FeatureStore.
215 41819 fdiaz
     *
216 40435 jjdelcerro
     * @param featureSet
217
     *            to extract data from
218
     * @param pageSize
219
     *            the number of elements per page data
220
     * @throws DataException
221
     *             if there is an error initializing the helper
222
     */
223
    public FeaturePagingHelperImpl(FeatureStore featureStore,
224
        FeatureQuery featureQuery, int pageSize) throws BaseException {
225
        super();
226 43660 jjdelcerro
        this.cachedPages = new PageCache(3);
227 40435 jjdelcerro
        FeatureQuery query = featureQuery;
228
        if (featureQuery == null) {
229
            query = featureStore.createFeatureQuery();
230
            query.setFeatureType(featureStore.getDefaultFeatureType());
231
        }
232
233
        this.featureStore = featureStore;
234
        this.query = query;
235
        this.query.setPageSize(pageSize);
236
237
        setDefaultCalculator(new Sizeable() {
238
            public long getSize() {
239
                    FeatureSet featureSet = getFeatureSet(false);
240
                try {
241
                                        return featureSet.getSize();
242
                } catch (BaseException e) {
243
                    LOG.error("Error getting the size of the FeatureSet: "
244
                        + featureSet, e);
245
                    return 0l;
246
                }
247
            }
248
        }, pageSize);
249 41819 fdiaz
250
251 40595 jldominguez
        if (LOG.isDebugEnabled()) {
252 41819 fdiaz
253 40595 jldominguez
            LOG.debug("FeaturePagingHelperImpl created with {} pages, "
254
                + "and a page size of {}", new Long(getCalculator()
255
                .getNumPages()), new Integer(pageSize));
256
        }
257 41212 jjdelcerro
        this.initialization_completed = true;
258 40435 jjdelcerro
    }
259
260
    /**
261
     * @return the selectionUp status
262
     */
263 41630 jjdelcerro
    public boolean isSelectionUp() {
264 40435 jjdelcerro
        return selectionUp;
265
    }
266 42807 jjdelcerro
267
    public FeatureSelection getSelection() {
268
        if (selection == null) {
269
            try {
270
                return getFeatureStore().getFeatureSelection();
271
            } catch (Exception e) {
272
                LOG.warn("Error getting the selection", e);
273
            }
274
        }
275
        return selection;
276
    }
277
278
    public void setSelection(FeatureSelection selection) {
279
        this.selection = selection;
280
    }
281
282
    @Override
283 40435 jjdelcerro
    public void setSelectionUp(boolean selectionUp) {
284
        this.selectionUp = selectionUp;
285
        try {
286 42807 jjdelcerro
            FeatureSelection currentSelection = getSelection();
287 41630 jjdelcerro
            if (selectionUp && !currentSelection.isEmpty()) {
288
                initialSelection =(FeatureSelection) currentSelection.clone();
289 40435 jjdelcerro
                setCalculator(new OneSubsetOneSetPagingCalculator(
290
                    new FeatureSetSizeableDelegate(initialSelection),
291
                    new FeatureSetSizeableDelegate(getFeatureSet(false)),
292
                    getMaxPageSize()));
293
            } else {
294
                if (initialSelection != null) {
295
                    initialSelection.dispose();
296
                    initialSelection = null;
297
                }
298
                setDefaultCalculator(new FeatureSetSizeableDelegate(
299
                    getFeatureSet(false)), getMaxPageSize());
300
            }
301
        } catch (BaseException e) {
302
            LOG.error("Error setting the selection up setting to: "
303
                + selectionUp, e);
304
        } catch (CloneNotSupportedException e) {
305
            LOG.error("Error cloning the selection "
306
                + "while setting the selection up", e);
307
        }
308
    }
309
310 42991 jbadia
    public synchronized Feature getFeatureAt(long index) throws BaseException {
311 40435 jjdelcerro
        // Check if we have currently loaded the viewed page data,
312
        // or we need to load a new one
313 42991 jbadia
            int maxPageSize = getMaxPageSize();
314
            long currentPage = getCurrentPage();
315
            long currentPage2 = currentPage;
316
317
318
        long pageForIndex = (long) Math.floor(index / maxPageSize);
319 40435 jjdelcerro
320 42991 jbadia
        if (pageForIndex != currentPage) {
321 40435 jjdelcerro
            setCurrentPage(pageForIndex);
322 42991 jbadia
            currentPage2 = getCurrentPage();
323 40435 jjdelcerro
        }
324
325 42991 jbadia
        long positionForIndex = index - (currentPage2 * maxPageSize);
326 40435 jjdelcerro
327 41268 jjdelcerro
        if (positionForIndex >= getCurrentPageFeatures().length) {
328 40435 jjdelcerro
            throw new FeatureIndexException(
329
                new IndexOutOfBoundsException("positionForIndex too big: "
330
                    + positionForIndex));
331
        } else {
332 41268 jjdelcerro
            Feature feature = getCurrentPageFeatures()[(int) positionForIndex];
333 41212 jjdelcerro
            return feature;
334 40435 jjdelcerro
        }
335 41819 fdiaz
336 40435 jjdelcerro
    }
337
338
    public Feature[] getCurrentPageFeatures() {
339 41268 jjdelcerro
        if( this.features==null ) {
340
            try {
341
                this.loadCurrentPageData();
342
            } catch (BaseException ex) {
343
                // Do nothing
344
            }
345
            if( this.features == null ) {
346
                String msg = "Can't retrieve the features from current page.";
347
                LOG.warn(msg);
348
                throw new RuntimeException(msg);
349
            }
350
        }
351 40435 jjdelcerro
        return features;
352
    }
353
354
    /**
355
     * Gets the feature set.
356
     * The boolean tells whether we must create the featureset
357
     * again (for example perhaps we need it after a feature
358
     * has been added/removed)
359
     */
360
    private FeatureSet getFeatureSet(boolean reset) {
361 41819 fdiaz
362 40435 jjdelcerro
        if (featSet == null || reset) {
363 41819 fdiaz
364 40435 jjdelcerro
            if (featSet != null) {
365
                try {
366
                    featSet.dispose();
367
                } catch (Exception ex) {
368
                    LOG.info("Error while disposing featset.", ex);
369
                }
370
            }
371 41819 fdiaz
372 40435 jjdelcerro
            try {
373 41819 fdiaz
                FeatureStore featureStore = getFeatureStore();
374 40435 jjdelcerro
                synchronized (featureStore) {
375 41819 fdiaz
                    featSet = featureStore.getFeatureSet(getFeatureQuery());
376 40435 jjdelcerro
                }
377
            } catch (DataException e) {
378
                throw new RuntimeException("Error getting a feature set with the query " + getFeatureQuery());
379
            }
380
        }
381
        return featSet;
382
    }
383 41819 fdiaz
384 43691 jjdelcerro
    @Override
385 40435 jjdelcerro
    public DynObjectSet getDynObjectSet() {
386
            return getFeatureSet(false).getDynObjectSet();
387
    }
388
389 43691 jjdelcerro
    @Override
390 40435 jjdelcerro
    public void reloadCurrentPage() throws BaseException {
391 41819 fdiaz
392 40435 jjdelcerro
        boolean sel_up = this.isSelectionUp();
393
394
        setSelectionUp(false);
395
        if (getCalculator().getCurrentPage() > -1) {
396 43691 jjdelcerro
            this.cachedPages.clear();
397 40435 jjdelcerro
            loadCurrentPageData();
398
        }
399 41819 fdiaz
400 40435 jjdelcerro
        if (sel_up) {
401
            setSelectionUp(true);
402
        }
403
    }
404
405 43691 jjdelcerro
    @Override
406 40435 jjdelcerro
    public void reload() throws BaseException {
407 41819 fdiaz
408 43726 jjdelcerro
        this.cachedPages.clear();
409 40435 jjdelcerro
        /*
410
         * Force re-creation of feature set
411
         */
412
        this.getFeatureSet(true);
413
414 41819 fdiaz
415 40435 jjdelcerro
        setDefaultCalculator(new Sizeable() {
416
            public long getSize() {
417
                    FeatureSet featureSet = getFeatureSet(false);
418
                try {
419
                                        return featureSet.getSize();
420
                } catch (BaseException e) {
421
                    LOG.error("Error getting the size of the FeatureSet: "
422
                        + featureSet, e);
423
                    return 0l;
424
                }
425
            }
426
        }, getCalculator().getMaxPageSize());
427
        reloadCurrentPage();
428
    }
429
430
    public FeatureStore getFeatureStore() {
431
        return featureStore;
432
    }
433
434
    public FeatureQuery getFeatureQuery() {
435
        return query;
436
    }
437
438
    /**
439
     * Loads all the Features of the current page.
440 43660 jjdelcerro
     * @throws org.gvsig.tools.exception.BaseException
441 40435 jjdelcerro
     */
442 43660 jjdelcerro
    @Override
443 42991 jbadia
    protected synchronized void loadCurrentPageData() throws BaseException {
444 41212 jjdelcerro
        if( !initialization_completed ) {
445
            return;
446
        }
447 40435 jjdelcerro
        final int currentPageSize = getCalculator().getCurrentPageSize();
448 43660 jjdelcerro
        final long currentPage = getCalculator().getCurrentPage();
449
        Page page = this.cachedPages.get(currentPage);
450
        if( page==null ) {
451
            page = new Page(currentPage, currentPageSize);
452 40435 jjdelcerro
453 43660 jjdelcerro
            long t1 = 0;
454
            if (LOG.isTraceEnabled()) {
455
                t1 = System.currentTimeMillis();
456
            }
457 40435 jjdelcerro
458 43660 jjdelcerro
            if (selectionUp) {
459
                loadCurrentPageDataWithSelectionUp(page);
460
            } else {
461
                loadCurrentPageDataNoSelection(page);
462
            }
463 40435 jjdelcerro
464 43660 jjdelcerro
            if (LOG.isTraceEnabled()) {
465
                long t2 = System.currentTimeMillis();
466
                LOG.trace("Time to load {} features: {} ms", currentPageSize, t2 - t1);
467
            }
468
            this.cachedPages.add(page);
469 40435 jjdelcerro
        }
470 43660 jjdelcerro
        this.features = page.getFeatures();
471 40435 jjdelcerro
    }
472 41819 fdiaz
473 43660 jjdelcerro
    private void loadCurrentPageDataWithSelectionUp(final Page page)
474 41630 jjdelcerro
            throws BaseException {
475 40435 jjdelcerro
        FeatureSelection selection = initialSelection;
476 41630 jjdelcerro
        if (selection == null) {
477 43660 jjdelcerro
            loadCurrentPageDataNoSelection(page);
478 41630 jjdelcerro
        } else {
479
            FeatureSet set = getFeatureSet(false);
480
            try {
481
                OneSubsetOneSetPagingCalculator twoSetsCalculator = null;
482
                if (getCalculator() instanceof OneSubsetOneSetPagingCalculator) {
483
                    twoSetsCalculator
484
                            = (OneSubsetOneSetPagingCalculator) getCalculator();
485
                } else {
486
                    twoSetsCalculator
487
                            = new OneSubsetOneSetPagingCalculator(
488
                                    new FeatureSetSizeableDelegate(selection),
489
                                    new FeatureSetSizeableDelegate(set),
490
                                    getMaxPageSize(), getCalculator().getCurrentPage());
491
                    setCalculator(twoSetsCalculator);
492
                }
493 40435 jjdelcerro
494
                // First load values from the selection, if the current page has
495 41630 jjdelcerro
                // elements from it
496
                if (twoSetsCalculator.hasCurrentPageAnyValuesInFirstSet()) {
497 43660 jjdelcerro
                    loadDataFromFeatureSet(page, 0, selection,
498 41630 jjdelcerro
                            twoSetsCalculator.getFirstSetInitialIndex(),
499
                            twoSetsCalculator.getFirstSetHowMany(), null);
500
                }
501 40435 jjdelcerro
                // Next, load values from the FeatureSet if the current page has values
502 41630 jjdelcerro
                // from it
503
                if (twoSetsCalculator.hasCurrentPageAnyValuesInSecondSet()) {
504
                    loadDataFromFeatureSet(
505 43660 jjdelcerro
                            page,
506 41630 jjdelcerro
                            // The cast will work as that size will be <= maxpagesize,
507
                            // which is an int
508
                            (int) twoSetsCalculator.getFirstSetHowMany(), set,
509
                            twoSetsCalculator.getSecondSetInitialIndex(),
510
                            twoSetsCalculator.getSecondSetHowMany(), selection);
511
                }
512
            } finally {
513
                /*
514
                 * This is the feature set
515
                 * we dont want to lose it
516
                 */
517
                // set.dispose();
518
            }
519 40435 jjdelcerro
        }
520
    }
521
522 43660 jjdelcerro
    private void loadCurrentPageDataNoSelection(final Page page)
523 40435 jjdelcerro
        throws BaseException {
524
525
        long firstPosition = getCalculator().getInitialIndex();
526
527
        if (LOG.isDebugEnabled()) {
528 43660 jjdelcerro
            LOG.debug("Loading {} Features starting at position {}",
529
                getCalculator().getCurrentPageSize(), firstPosition
530
            );
531 40435 jjdelcerro
        }
532
533
        FeatureSet featureSet = getFeatureSet(false);
534
        try {
535 43660 jjdelcerro
                loadDataFromFeatureSet(page, 0, featureSet, firstPosition,
536 40435 jjdelcerro
                                getCalculator().getCurrentPageSize(), null);
537
        } catch(DataException ex) {
538
            throw ex;
539
            // } finally {
540
                // featureSet.dispose();
541
        }
542 41819 fdiaz
543 40435 jjdelcerro
    }
544
545 43660 jjdelcerro
    private void loadDataFromFeatureSet(final Page page,
546 40435 jjdelcerro
        final int valuesPosition, FeatureSet set, long initialIndex,
547
        final long howMany, final FeatureSelection selectedFeaturesToSkip)
548
        throws DataException {
549
550
        try {
551
            set.accept(new Visitor() {
552
                private int i = valuesPosition;
553
554 43660 jjdelcerro
                @Override
555 40435 jjdelcerro
                public void visit(Object obj) throws VisitCanceledException,
556
                    BaseException {
557
                    if (i >= valuesPosition + howMany) {
558
                        throw new VisitCanceledException();
559
                    }
560
                    Feature current = (Feature) obj;
561
                    // Add the current Feature only if we don't skip selected
562
                    // features or the feature is not selected
563
                    if (selectedFeaturesToSkip == null
564
                        || !selectedFeaturesToSkip.isSelected(current)) {
565 41630 jjdelcerro
                        try {
566 43660 jjdelcerro
                            page.setFeature(i,current.getCopy());
567 41630 jjdelcerro
                            i++;
568
                        } catch(Exception ex) {
569
                            // Aqui no deberia petar, pero...
570
                            // me he encontrado un caso que tenia una referencia a
571 41819 fdiaz
                            // una feature seleccionada que ya no existia. No se como
572 41630 jjdelcerro
                            // habia pasado, se habia quedado de antes guardada en el
573
                            // proyecto pero la feature ya no existia, y eso hacia que
574
                            // petase al intentar leer de disco la feature a partir
575
                            // de una referencia no valida.
576
                        }
577 40435 jjdelcerro
                    }
578
                }
579 43358 jjdelcerro
            }, initialIndex, howMany);
580
        } catch(VisitCanceledException ex) {
581
            // Do nothing
582 40435 jjdelcerro
        } catch (BaseException e) {
583
            if (e instanceof DataException) {
584
                throw ((DataException) e);
585
            } else {
586
                LOG.error("Error loading the data starting at position {}",
587
                    new Long(initialIndex), e);
588
            }
589
        }
590
    }
591
592
    public void delete(Feature feature) throws BaseException {
593
        featureStore.delete(feature);
594
        /*
595
         * Force re-creation of feature set
596
         */
597
        this.getFeatureSet(true);
598
599
        reloadCurrentPage();
600
    }
601
602
    public void insert(EditableFeature feature) throws BaseException {
603
            featureStore.insert(feature);
604
        /*
605
         * Force re-creation of feature set
606
         */
607
        this.getFeatureSet(true);
608
609
        reloadCurrentPage();
610
    }
611
612
    public void update(EditableFeature feature) throws BaseException {
613
            featureStore.update(feature);
614
        /*
615
         * Force re-creation of feature set
616
         */
617
        this.getFeatureSet(true);
618
619
        reloadCurrentPage();
620
    }
621
622
    public FeatureType getFeatureType() {
623 41819 fdiaz
624 40435 jjdelcerro
        FeatureType ft = null;
625 41819 fdiaz
626 40435 jjdelcerro
        try {
627
            ft = featureStore.getDefaultFeatureType();
628
        } catch (DataException e) {
629
            LOG.error("Error while getting feature type: " +
630
                e.getMessage(), e);
631
        }
632
        return ft;
633 41819 fdiaz
634 40435 jjdelcerro
        /*
635 41819 fdiaz
         *
636 40435 jjdelcerro
        FeatureSet featureSet = getFeatureSet();
637
        try {
638
            return featureSet.getDefaultFeatureType();
639
        } finally {
640
            featureSet.dispose();
641
        }
642
        */
643
644 41819 fdiaz
645 40435 jjdelcerro
    }
646
647
    protected void doDispose() throws BaseException {
648
        initialSelection.dispose();
649
        if (featSet != null) {
650
            try {
651
                featSet.dispose();
652
            } catch (Exception ex) {
653
                LOG.info("Error while disposing featset.", ex);
654
            }
655
        }
656
    }
657
658
    public DynObject[] getCurrentPageDynObjects() {
659
        Feature[] features = getCurrentPageFeatures();
660
        DynObject[] dynobjects = new DynObject[features.length];
661
        for (int i = 0; i < dynobjects.length; i++) {
662
            dynobjects[i] = new DynObjectFeatureFacade(features[i]);
663
        }
664
        return dynobjects;
665
    }
666
667
    public DynObject getDynObjectAt(long index) throws BaseException {
668
        return new DynObjectFeatureFacade(getFeatureAt(index));
669
    }
670
671 41212 jjdelcerro
    public List asList() {
672
        return new FeaturePagingHelperList();
673
    }
674 41819 fdiaz
675 41212 jjdelcerro
    public List asListOfDynObjects() {
676
        return new DynObjectPagingHelperList();
677 41819 fdiaz
    }
678
679 41212 jjdelcerro
    private class FeaturePagingHelperList extends PagingHelperList {
680
        public Object get(int i) {
681
            try {
682
                return getFeatureAt(i);
683
            } catch (BaseException ex) {
684
                throw  new RuntimeException(ex);
685
            }
686
        }
687
    }
688 41819 fdiaz
689 41212 jjdelcerro
    private class DynObjectPagingHelperList extends PagingHelperList {
690
        public Object get(int i) {
691
            try {
692
                return getDynObjectAt(i);
693
            } catch (BaseException ex) {
694
                throw  new RuntimeException(ex);
695
            }
696
        }
697 42775 jjdelcerro
698 41212 jjdelcerro
    }
699 41819 fdiaz
700 42775 jjdelcerro
    private abstract class PagingHelperList implements List,  FacadeOfAFeaturePagingHelper {
701 41212 jjdelcerro
702 42775 jjdelcerro
        @Override
703
        public FeaturePagingHelper getFeaturePagingHelper() {
704
            return FeaturePagingHelperImpl.this;
705
        }
706
707 41212 jjdelcerro
        public int size() {
708
            try {
709
                return (int) getFeatureSet(false).getSize();
710
            } catch (DataException ex) {
711
                throw  new RuntimeException(ex);
712
            }
713
        }
714
715
        public boolean isEmpty() {
716
            try {
717
                return getFeatureSet(false).isEmpty();
718
            } catch (DataException ex) {
719
                throw  new RuntimeException(ex);
720 41819 fdiaz
            } catch (ConcurrentDataModificationException ex) {
721
                LOG.warn(
722
                    "Error to asking about the emptiness of the store. Retrying reloading data.",
723
                    ex);
724
                try {
725
                    reload();
726
                } catch (BaseException e) {
727
                    LOG.warn("Error reloading data.", e);
728
                    throw new RuntimeException(e);
729
                }
730
                try {
731
                    return getFeatureSet(false).isEmpty();
732
                } catch (DataException e) {
733
                    LOG.warn(
734
                        "Error to asking about the emptiness of the store after reloading data.",
735
                        e);
736
                    throw new RuntimeException(e);
737
                }
738 41212 jjdelcerro
            }
739
        }
740
741
        public Iterator iterator() {
742
            try {
743
                return getFeatureSet(false).fastIterator();
744
            } catch (DataException ex) {
745
                throw  new RuntimeException(ex);
746
            }
747
        }
748
749
        public boolean contains(Object o) {
750
            throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
751
        }
752
753
        public Object[] toArray() {
754
            throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
755
        }
756
757
        public Object[] toArray(Object[] ts) {
758
            throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
759
        }
760
761
        public boolean add(Object e) {
762
            throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
763
        }
764
765
        public boolean remove(Object o) {
766
            throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
767
        }
768
769
        public boolean containsAll(Collection clctn) {
770
            throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
771
        }
772
773
        public boolean addAll(Collection clctn) {
774
            throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
775
        }
776
777
        public boolean addAll(int i, Collection clctn) {
778
            throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
779
        }
780
781
        public boolean removeAll(Collection clctn) {
782
            throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
783
        }
784
785
        public boolean retainAll(Collection clctn) {
786
            throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
787
        }
788
789
        public void clear() {
790
            throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
791
        }
792
793
        public Object set(int i, Object e) {
794
            throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
795
        }
796
797
        public void add(int i, Object e) {
798
            throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
799
        }
800
801
        public Object remove(int i) {
802
            throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
803
        }
804
805
        public int indexOf(Object o) {
806
            throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
807
        }
808
809
        public int lastIndexOf(Object o) {
810
            throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
811
        }
812
813
        public ListIterator listIterator() {
814
            throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
815
        }
816
817
        public ListIterator listIterator(int i) {
818
            throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
819
        }
820
821
        public List subList(int i, int i1) {
822
            throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
823
        }
824 41819 fdiaz
825 41212 jjdelcerro
    }
826 40435 jjdelcerro
}