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

History | View | Annotate | Download (25.2 KB)

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

    
26
import java.util.Collection;
27
import java.util.Iterator;
28
import java.util.List;
29
import java.util.ListIterator;
30
import org.slf4j.Logger;
31
import org.slf4j.LoggerFactory;
32

    
33
import org.gvsig.fmap.dal.exception.DataException;
34
import org.gvsig.fmap.dal.feature.EditableFeature;
35
import org.gvsig.fmap.dal.feature.Feature;
36
import org.gvsig.fmap.dal.feature.FeatureQuery;
37
import org.gvsig.fmap.dal.feature.FeatureSelection;
38
import org.gvsig.fmap.dal.feature.FeatureSet;
39
import org.gvsig.fmap.dal.feature.FeatureStore;
40
import org.gvsig.fmap.dal.feature.FeatureType;
41
import org.gvsig.fmap.dal.feature.exception.ConcurrentDataModificationException;
42
import org.gvsig.fmap.dal.feature.exception.FeatureIndexException;
43
import org.gvsig.fmap.dal.feature.impl.dynobjectutils.DynObjectFeatureFacade;
44
import org.gvsig.fmap.dal.feature.paging.FacadeOfAFeaturePagingHelper;
45
import org.gvsig.fmap.dal.feature.paging.FeaturePagingHelper;
46
import org.gvsig.tools.dynobject.DynObject;
47
import org.gvsig.tools.dynobject.DynObjectSet;
48
import org.gvsig.tools.dynobject.impl.DefaultDynObjectPagingHelper;
49
import org.gvsig.tools.exception.BaseException;
50
import org.gvsig.tools.visitor.VisitCanceledException;
51
import org.gvsig.tools.visitor.Visitor;
52

    
53
/**
54
 * Helper class to access the values of a FeatureCollection by position. Handles
55
 * pagination automatically to avoid filling the memory in case of big
56
 * collections.
57
 *
58
 * TODO: evaluate if its more convenient to read values in the background when
59
 * the returned value is near the end of the page, instead of loading a page on
60
 * demand.
61
 *
62
 * @author gvSIG Team
63
 */
64
public class FeaturePagingHelperImpl extends DefaultDynObjectPagingHelper
65
    implements FeaturePagingHelper {
66

    
67
    private static final Logger LOG = LoggerFactory
68
        .getLogger(FeaturePagingHelperImpl.class);
69

    
70
    private FeatureQuery query;
71

    
72
    private FeatureStore featureStore;
73

    
74
    /** If the selected Features must be returned as the first ones. **/
75
    private boolean selectionUp = false;
76

    
77
    private FeatureSet featSet = null;
78
    private FeatureSelection initialSelection = null;
79

    
80
    private Feature[] features = null;
81

    
82
    private boolean initialization_completed = false;
83

    
84
    private FeatureSelection selection = null;
85
    /**
86
     * Constructs a FeaturePagingHelperImpl from data of a FeatureStore.
87
     *
88
     * @param featureStore
89
     *            to extract data from
90
     * @throws DataException
91
     *             if there is an error initializing the helper
92
     */
93
    public FeaturePagingHelperImpl(FeatureStore featureStore)
94
        throws BaseException {
95
        this(featureStore, DEFAULT_PAGE_SIZE);
96
    }
97

    
98
    /**
99
     * Constructs a FeaturePagingHelperImpl from data of a FeatureStore.
100
     *
101
     * @param featureStore
102
     *            to extract data from
103
     * @param pageSize
104
     *            the number of elements per page data
105
     * @throws DataException
106
     *             if there is an error initializing the helper
107
     */
108
    public FeaturePagingHelperImpl(FeatureStore featureStore, int pageSize)
109
        throws BaseException {
110
        this(featureStore, null, pageSize);
111
    }
112

    
113
    /**
114
     * Constructs a FeaturePagingHelperImpl from data of a FeatureStore.
115
     *
116
     * @param featureStore
117
     *            to extract data from
118
     * @throws DataException
119
     *             if there is an error initializing the helper
120
     */
121
    public FeaturePagingHelperImpl(FeatureStore featureStore,
122
        FeatureQuery featureQuery) throws BaseException {
123
        this(featureStore, featureQuery, DEFAULT_PAGE_SIZE);
124
    }
125

    
126
    /**
127
     * Constructs a FeaturePagingHelperImpl from data of a FeatureStore.
128
     *
129
     * @param featureSet
130
     *            to extract data from
131
     * @param pageSize
132
     *            the number of elements per page data
133
     * @throws DataException
134
     *             if there is an error initializing the helper
135
     */
136
    public FeaturePagingHelperImpl(FeatureStore featureStore,
137
        FeatureQuery featureQuery, int pageSize) throws BaseException {
138
        super();
139
        FeatureQuery query = featureQuery;
140
        if (featureQuery == null) {
141
            query = featureStore.createFeatureQuery();
142
            query.setFeatureType(featureStore.getDefaultFeatureType());
143
        }
144

    
145
        this.featureStore = featureStore;
146
        this.query = query;
147
        this.query.setPageSize(pageSize);
148

    
149
        setDefaultCalculator(new Sizeable() {
150
            public long getSize() {
151
                    FeatureSet featureSet = getFeatureSet(false);
152
                try {
153
                                        return featureSet.getSize();
154
                } catch (BaseException e) {
155
                    LOG.error("Error getting the size of the FeatureSet: "
156
                        + featureSet, e);
157
                    return 0l;
158
                }
159
            }
160
        }, pageSize);
161

    
162

    
163
        if (LOG.isDebugEnabled()) {
164

    
165
            LOG.debug("FeaturePagingHelperImpl created with {} pages, "
166
                + "and a page size of {}", new Long(getCalculator()
167
                .getNumPages()), new Integer(pageSize));
168
        }
169
        this.initialization_completed = true;
170
    }
171

    
172
    /**
173
     * @return the selectionUp status
174
     */
175
    public boolean isSelectionUp() {
176
        return selectionUp;
177
    }
178
    
179
    public FeatureSelection getSelection() {
180
        if (selection == null) {
181
            try {
182
                return getFeatureStore().getFeatureSelection();
183
            } catch (Exception e) {
184
                LOG.warn("Error getting the selection", e);
185
            }
186
        }
187
        return selection;
188
    }
189
    
190
    public void setSelection(FeatureSelection selection) {
191
        this.selection = selection;
192
    }
193
    
194
    @Override
195
    public void setSelectionUp(boolean selectionUp) {
196
        this.selectionUp = selectionUp;
197
        try {
198
            FeatureSelection currentSelection = getSelection();
199
            if (selectionUp && !currentSelection.isEmpty()) {
200
                initialSelection =(FeatureSelection) currentSelection.clone();
201
                setCalculator(new OneSubsetOneSetPagingCalculator(
202
                    new FeatureSetSizeableDelegate(initialSelection),
203
                    new FeatureSetSizeableDelegate(getFeatureSet(false)),
204
                    getMaxPageSize()));
205
            } else {
206
                if (initialSelection != null) {
207
                    initialSelection.dispose();
208
                    initialSelection = null;
209
                }
210
                setDefaultCalculator(new FeatureSetSizeableDelegate(
211
                    getFeatureSet(false)), getMaxPageSize());
212
            }
213
        } catch (BaseException e) {
214
            LOG.error("Error setting the selection up setting to: "
215
                + selectionUp, e);
216
        } catch (CloneNotSupportedException e) {
217
            LOG.error("Error cloning the selection "
218
                + "while setting the selection up", e);
219
        }
220
    }
221

    
222
    public synchronized Feature getFeatureAt(long index) throws BaseException {
223
        // Check if we have currently loaded the viewed page data,
224
        // or we need to load a new one
225
            int maxPageSize = getMaxPageSize();
226
            long currentPage = getCurrentPage();
227
            long currentPage2 = currentPage;
228
            
229
            
230
        long pageForIndex = (long) Math.floor(index / maxPageSize);
231

    
232
        if (pageForIndex != currentPage) {
233
            setCurrentPage(pageForIndex);
234
            currentPage2 = getCurrentPage();
235
        }
236

    
237
        long positionForIndex = index - (currentPage2 * maxPageSize);
238

    
239
        if (positionForIndex >= getCurrentPageFeatures().length) {
240
            throw new FeatureIndexException(
241
                new IndexOutOfBoundsException("positionForIndex too big: "
242
                    + positionForIndex));
243
        } else {
244
            Feature feature = getCurrentPageFeatures()[(int) positionForIndex];
245
            return feature;
246
        }
247

    
248
    }
249

    
250
    public Feature[] getCurrentPageFeatures() {
251
        if( this.features==null ) {
252
            try {
253
                this.loadCurrentPageData();
254
            } catch (BaseException ex) {
255
                // Do nothing
256
            }
257
            if( this.features == null ) {
258
                String msg = "Can't retrieve the features from current page.";
259
                LOG.warn(msg);
260
                throw new RuntimeException(msg);
261
            }
262
        }
263
        return features;
264
    }
265

    
266
    /**
267
     * Gets the feature set.
268
     * The boolean tells whether we must create the featureset
269
     * again (for example perhaps we need it after a feature
270
     * has been added/removed)
271
     */
272
    private FeatureSet getFeatureSet(boolean reset) {
273

    
274
        if (featSet == null || reset) {
275

    
276
            if (featSet != null) {
277
                try {
278
                    featSet.dispose();
279
                } catch (Exception ex) {
280
                    LOG.info("Error while disposing featset.", ex);
281
                }
282
            }
283

    
284
            try {
285
                FeatureStore featureStore = getFeatureStore();
286
                synchronized (featureStore) {
287
                    featSet = featureStore.getFeatureSet(getFeatureQuery());
288
                }
289
            } catch (DataException e) {
290
                throw new RuntimeException("Error getting a feature set with the query " + getFeatureQuery());
291
            }
292
        }
293
        return featSet;
294
    }
295

    
296
    public DynObjectSet getDynObjectSet() {
297
            return getFeatureSet(false).getDynObjectSet();
298
    }
299

    
300
    public void reloadCurrentPage() throws BaseException {
301

    
302
        boolean sel_up = this.isSelectionUp();
303

    
304
        setSelectionUp(false);
305
        if (getCalculator().getCurrentPage() > -1) {
306
            loadCurrentPageData();
307
        }
308

    
309
        if (sel_up) {
310
            setSelectionUp(true);
311
        }
312
    }
313

    
314
    public void reload() throws BaseException {
315

    
316
        /*
317
         * Force re-creation of feature set
318
         */
319
        this.getFeatureSet(true);
320

    
321

    
322
        setDefaultCalculator(new Sizeable() {
323
            public long getSize() {
324
                    FeatureSet featureSet = getFeatureSet(false);
325
                try {
326
                                        return featureSet.getSize();
327
                } catch (BaseException e) {
328
                    LOG.error("Error getting the size of the FeatureSet: "
329
                        + featureSet, e);
330
                    return 0l;
331
                }
332
            }
333
        }, getCalculator().getMaxPageSize());
334
        reloadCurrentPage();
335
    }
336

    
337
    public FeatureStore getFeatureStore() {
338
        return featureStore;
339
    }
340

    
341
    public FeatureQuery getFeatureQuery() {
342
        return query;
343
    }
344

    
345
    /**
346
     * Loads all the Features of the current page.
347
     */
348
    protected synchronized void loadCurrentPageData() throws BaseException {
349
        if( !initialization_completed ) {
350
            return;
351
        }
352
        final int currentPageSize = getCalculator().getCurrentPageSize();
353
        final Feature[] values = new Feature[currentPageSize];
354

    
355
        long t1 = 0;
356
        if (LOG.isTraceEnabled()) {
357
            t1 = System.currentTimeMillis();
358
        }
359

    
360
        if (selectionUp) {
361
            loadCurrentPageDataWithSelectionUp(values);
362
        } else {
363
            loadCurrentPageDataNoSelection(values);
364
        }
365

    
366
        if (LOG.isTraceEnabled()) {
367
            long t2 = System.currentTimeMillis();
368
            LOG.trace("Time to load {} features: {} ms", new Integer(
369
                currentPageSize), new Long(t2 - t1));
370
        }
371

    
372
        this.features = values;
373
    }
374

    
375
    private void loadCurrentPageDataWithSelectionUp(final Feature[] values)
376
            throws BaseException {
377
        FeatureSelection selection = initialSelection;
378
        if (selection == null) {
379
            loadCurrentPageDataNoSelection(values);
380
        } else {
381
            FeatureSet set = getFeatureSet(false);
382
            try {
383
                OneSubsetOneSetPagingCalculator twoSetsCalculator = null;
384
                if (getCalculator() instanceof OneSubsetOneSetPagingCalculator) {
385
                    twoSetsCalculator
386
                            = (OneSubsetOneSetPagingCalculator) getCalculator();
387
                } else {
388
                    twoSetsCalculator
389
                            = new OneSubsetOneSetPagingCalculator(
390
                                    new FeatureSetSizeableDelegate(selection),
391
                                    new FeatureSetSizeableDelegate(set),
392
                                    getMaxPageSize(), getCalculator().getCurrentPage());
393
                    setCalculator(twoSetsCalculator);
394
                }
395

    
396
                // First load values from the selection, if the current page has
397
                // elements from it
398
                if (twoSetsCalculator.hasCurrentPageAnyValuesInFirstSet()) {
399
                    loadDataFromFeatureSet(values, 0, selection,
400
                            twoSetsCalculator.getFirstSetInitialIndex(),
401
                            twoSetsCalculator.getFirstSetHowMany(), null);
402
                }
403
                // Next, load values from the FeatureSet if the current page has values
404
                // from it
405
                if (twoSetsCalculator.hasCurrentPageAnyValuesInSecondSet()) {
406
                    loadDataFromFeatureSet(
407
                            values,
408
                            // The cast will work as that size will be <= maxpagesize,
409
                            // which is an int
410
                            (int) twoSetsCalculator.getFirstSetHowMany(), set,
411
                            twoSetsCalculator.getSecondSetInitialIndex(),
412
                            twoSetsCalculator.getSecondSetHowMany(), selection);
413
                }
414
            } finally {
415
                /*
416
                 * This is the feature set
417
                 * we dont want to lose it
418
                 */
419
                // set.dispose();
420
            }
421
        }
422
    }
423

    
424
    private void loadCurrentPageDataNoSelection(final Feature[] values)
425
        throws BaseException {
426

    
427
        long firstPosition = getCalculator().getInitialIndex();
428

    
429
        if (LOG.isDebugEnabled()) {
430
            LOG.debug("Loading {} Features starting at position {}",
431
                new Integer(getCalculator().getCurrentPageSize()), new Long(
432
                    firstPosition));
433
        }
434

    
435
        FeatureSet featureSet = getFeatureSet(false);
436
        try {
437
                loadDataFromFeatureSet(values, 0, featureSet, firstPosition,
438
                                getCalculator().getCurrentPageSize(), null);
439
        } catch(DataException ex) {
440
            throw ex;
441
            // } finally {
442
                // featureSet.dispose();
443
        }
444

    
445
    }
446

    
447
    private void loadDataFromFeatureSet(final Feature[] values,
448
        final int valuesPosition, FeatureSet set, long initialIndex,
449
        final long howMany, final FeatureSelection selectedFeaturesToSkip)
450
        throws DataException {
451

    
452
        try {
453
            set.accept(new Visitor() {
454

    
455
                private int i = valuesPosition;
456

    
457
                public void visit(Object obj) throws VisitCanceledException,
458
                    BaseException {
459
                    if (i >= valuesPosition + howMany) {
460
                        throw new VisitCanceledException();
461
                    }
462
                    Feature current = (Feature) obj;
463
                    // Add the current Feature only if we don't skip selected
464
                    // features or the feature is not selected
465
                    if (selectedFeaturesToSkip == null
466
                        || !selectedFeaturesToSkip.isSelected(current)) {
467
                        try {
468
                            values[i] = current.getCopy();
469
                            i++;
470
                        } catch(Exception ex) {
471
                            // Aqui no deberia petar, pero...
472
                            // me he encontrado un caso que tenia una referencia a
473
                            // una feature seleccionada que ya no existia. No se como
474
                            // habia pasado, se habia quedado de antes guardada en el
475
                            // proyecto pero la feature ya no existia, y eso hacia que
476
                            // petase al intentar leer de disco la feature a partir
477
                            // de una referencia no valida.
478
                        }
479
                    }
480
                }
481
            }, initialIndex);
482
        } catch (BaseException e) {
483
            if (e instanceof DataException) {
484
                throw ((DataException) e);
485
            } else {
486
                LOG.error("Error loading the data starting at position {}",
487
                    new Long(initialIndex), e);
488
            }
489
        }
490
    }
491

    
492
    public void delete(Feature feature) throws BaseException {
493
        featureStore.delete(feature);
494
        /*
495
         * Force re-creation of feature set
496
         */
497
        this.getFeatureSet(true);
498

    
499
        reloadCurrentPage();
500
    }
501

    
502
    public void insert(EditableFeature feature) throws BaseException {
503
            featureStore.insert(feature);
504
        /*
505
         * Force re-creation of feature set
506
         */
507
        this.getFeatureSet(true);
508

    
509
        reloadCurrentPage();
510
    }
511

    
512
    public void update(EditableFeature feature) throws BaseException {
513
            featureStore.update(feature);
514
        /*
515
         * Force re-creation of feature set
516
         */
517
        this.getFeatureSet(true);
518

    
519
        reloadCurrentPage();
520
    }
521

    
522
    public FeatureType getFeatureType() {
523

    
524
        FeatureType ft = null;
525

    
526
        try {
527
            ft = featureStore.getDefaultFeatureType();
528
        } catch (DataException e) {
529
            LOG.error("Error while getting feature type: " +
530
                e.getMessage(), e);
531
        }
532
        return ft;
533

    
534
        /*
535
         *
536
        FeatureSet featureSet = getFeatureSet();
537
        try {
538
            return featureSet.getDefaultFeatureType();
539
        } finally {
540
            featureSet.dispose();
541
        }
542
        */
543

    
544

    
545
    }
546

    
547
    protected void doDispose() throws BaseException {
548
        initialSelection.dispose();
549
        if (featSet != null) {
550
            try {
551
                featSet.dispose();
552
            } catch (Exception ex) {
553
                LOG.info("Error while disposing featset.", ex);
554
            }
555
        }
556
    }
557

    
558
    public DynObject[] getCurrentPageDynObjects() {
559
        Feature[] features = getCurrentPageFeatures();
560
        DynObject[] dynobjects = new DynObject[features.length];
561
        for (int i = 0; i < dynobjects.length; i++) {
562
            dynobjects[i] = new DynObjectFeatureFacade(features[i]);
563
        }
564
        return dynobjects;
565
    }
566

    
567
    public DynObject getDynObjectAt(long index) throws BaseException {
568
        return new DynObjectFeatureFacade(getFeatureAt(index));
569
    }
570

    
571
    public List asList() {
572
        return new FeaturePagingHelperList();
573
    }
574

    
575
    public List asListOfDynObjects() {
576
        return new DynObjectPagingHelperList();
577
    }
578

    
579
    private class FeaturePagingHelperList extends PagingHelperList {
580
        public Object get(int i) {
581
            try {
582
                return getFeatureAt(i);
583
            } catch (BaseException ex) {
584
                throw  new RuntimeException(ex);
585
            }
586
        }
587
    }
588

    
589
    private class DynObjectPagingHelperList extends PagingHelperList {
590
        public Object get(int i) {
591
            try {
592
                return getDynObjectAt(i);
593
            } catch (BaseException ex) {
594
                throw  new RuntimeException(ex);
595
            }
596
        }
597

    
598
    }
599

    
600
    private abstract class PagingHelperList implements List,  FacadeOfAFeaturePagingHelper {
601

    
602
        @Override
603
        public FeaturePagingHelper getFeaturePagingHelper() {
604
            return FeaturePagingHelperImpl.this;
605
        }
606
        
607
        public int size() {
608
            try {
609
                return (int) getFeatureSet(false).getSize();
610
            } catch (DataException ex) {
611
                throw  new RuntimeException(ex);
612
            }
613
        }
614

    
615
        public boolean isEmpty() {
616
            try {
617
                return getFeatureSet(false).isEmpty();
618
            } catch (DataException ex) {
619
                throw  new RuntimeException(ex);
620
            } catch (ConcurrentDataModificationException ex) {
621
                LOG.warn(
622
                    "Error to asking about the emptiness of the store. Retrying reloading data.",
623
                    ex);
624
                try {
625
                    reload();
626
                } catch (BaseException e) {
627
                    LOG.warn("Error reloading data.", e);
628
                    throw new RuntimeException(e);
629
                }
630
                try {
631
                    return getFeatureSet(false).isEmpty();
632
                } catch (DataException e) {
633
                    LOG.warn(
634
                        "Error to asking about the emptiness of the store after reloading data.",
635
                        e);
636
                    throw new RuntimeException(e);
637
                }
638
            }
639
        }
640

    
641
        public Iterator iterator() {
642
            try {
643
                return getFeatureSet(false).fastIterator();
644
            } catch (DataException ex) {
645
                throw  new RuntimeException(ex);
646
            }
647
        }
648

    
649
        public boolean contains(Object o) {
650
            throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
651
        }
652

    
653
        public Object[] toArray() {
654
            throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
655
        }
656

    
657
        public Object[] toArray(Object[] ts) {
658
            throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
659
        }
660

    
661
        public boolean add(Object e) {
662
            throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
663
        }
664

    
665
        public boolean remove(Object o) {
666
            throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
667
        }
668

    
669
        public boolean containsAll(Collection clctn) {
670
            throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
671
        }
672

    
673
        public boolean addAll(Collection clctn) {
674
            throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
675
        }
676

    
677
        public boolean addAll(int i, Collection clctn) {
678
            throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
679
        }
680

    
681
        public boolean removeAll(Collection clctn) {
682
            throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
683
        }
684

    
685
        public boolean retainAll(Collection clctn) {
686
            throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
687
        }
688

    
689
        public void clear() {
690
            throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
691
        }
692

    
693
        public Object set(int i, Object e) {
694
            throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
695
        }
696

    
697
        public void add(int i, Object e) {
698
            throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
699
        }
700

    
701
        public Object remove(int i) {
702
            throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
703
        }
704

    
705
        public int indexOf(Object o) {
706
            throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
707
        }
708

    
709
        public int lastIndexOf(Object o) {
710
            throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
711
        }
712

    
713
        public ListIterator listIterator() {
714
            throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
715
        }
716

    
717
        public ListIterator listIterator(int i) {
718
            throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
719
        }
720

    
721
        public List subList(int i, int i1) {
722
            throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
723
        }
724

    
725
    }
726
}