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 @ 45425
History | View | Annotate | Download (34 KB)
1 | 40559 | jjdelcerro | /**
|
---|---|---|---|
2 | * gvSIG. Desktop Geographic Information System.
|
||
3 | 40435 | jjdelcerro | *
|
4 | 44977 | jjdelcerro | * Copyright (C) 2007-2020 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 | 45425 | jjdelcerro | import java.util.logging.Level; |
33 | 44840 | jjdelcerro | import org.apache.commons.lang3.mutable.MutableBoolean; |
34 | 40435 | jjdelcerro | import org.slf4j.Logger; |
35 | import org.slf4j.LoggerFactory; |
||
36 | |||
37 | import org.gvsig.fmap.dal.exception.DataException; |
||
38 | import org.gvsig.fmap.dal.feature.EditableFeature; |
||
39 | import org.gvsig.fmap.dal.feature.Feature; |
||
40 | import org.gvsig.fmap.dal.feature.FeatureQuery; |
||
41 | import org.gvsig.fmap.dal.feature.FeatureSelection; |
||
42 | import org.gvsig.fmap.dal.feature.FeatureSet; |
||
43 | import org.gvsig.fmap.dal.feature.FeatureStore; |
||
44 | import org.gvsig.fmap.dal.feature.FeatureType; |
||
45 | 41819 | fdiaz | import org.gvsig.fmap.dal.feature.exception.ConcurrentDataModificationException; |
46 | 40435 | jjdelcerro | import org.gvsig.fmap.dal.feature.exception.FeatureIndexException; |
47 | 42775 | jjdelcerro | import org.gvsig.fmap.dal.feature.impl.dynobjectutils.DynObjectFeatureFacade; |
48 | import org.gvsig.fmap.dal.feature.paging.FacadeOfAFeaturePagingHelper; |
||
49 | 40435 | jjdelcerro | import org.gvsig.fmap.dal.feature.paging.FeaturePagingHelper; |
50 | 45196 | jjdelcerro | import org.gvsig.tools.dispose.Disposable; |
51 | 45425 | jjdelcerro | import org.gvsig.tools.dispose.DisposeUtils; |
52 | 40435 | jjdelcerro | import org.gvsig.tools.dynobject.DynObject; |
53 | import org.gvsig.tools.dynobject.DynObjectSet; |
||
54 | import org.gvsig.tools.dynobject.impl.DefaultDynObjectPagingHelper; |
||
55 | import org.gvsig.tools.exception.BaseException; |
||
56 | 44253 | jjdelcerro | import org.gvsig.tools.util.UnmodifiableBasicList; |
57 | import org.gvsig.tools.util.UnmodifiableBasicList64; |
||
58 | 40435 | jjdelcerro | import org.gvsig.tools.visitor.VisitCanceledException; |
59 | import org.gvsig.tools.visitor.Visitor; |
||
60 | |||
61 | /**
|
||
62 | * Helper class to access the values of a FeatureCollection by position. Handles
|
||
63 | * pagination automatically to avoid filling the memory in case of big
|
||
64 | * collections.
|
||
65 | 41819 | fdiaz | *
|
66 | 40435 | jjdelcerro | * TODO: evaluate if its more convenient to read values in the background when
|
67 | * the returned value is near the end of the page, instead of loading a page on
|
||
68 | * demand.
|
||
69 | 41819 | fdiaz | *
|
70 | 40435 | jjdelcerro | * @author gvSIG Team
|
71 | */
|
||
72 | 44977 | jjdelcerro | @SuppressWarnings("UseSpecificCatch") |
73 | 40435 | jjdelcerro | public class FeaturePagingHelperImpl extends DefaultDynObjectPagingHelper |
74 | 44977 | jjdelcerro | implements FeaturePagingHelper {
|
75 | 40435 | jjdelcerro | |
76 | 43660 | jjdelcerro | private static final Logger LOG = LoggerFactory.getLogger(FeaturePagingHelperImpl.class); |
77 | 40435 | jjdelcerro | |
78 | 43660 | jjdelcerro | private static class Page { |
79 | |||
80 | 43691 | jjdelcerro | private Feature[] features; |
81 | 43660 | jjdelcerro | private final long number; |
82 | private final int size; |
||
83 | private long lastaccess; |
||
84 | 44977 | jjdelcerro | |
85 | 43660 | jjdelcerro | public Page(long number, int size) { |
86 | this.size = size;
|
||
87 | this.number = number;
|
||
88 | this.features = new Feature[size]; |
||
89 | this.lastaccess = 0; |
||
90 | } |
||
91 | |||
92 | public void setFeature(int i, Feature copy) { |
||
93 | this.features[i] = copy;
|
||
94 | } |
||
95 | 44977 | jjdelcerro | |
96 | 43660 | jjdelcerro | public Feature[] getFeatures() { |
97 | this.lastaccess = (new Date()).getTime(); |
||
98 | return this.features; |
||
99 | } |
||
100 | 44977 | jjdelcerro | |
101 | 43660 | jjdelcerro | public long getPageNumber() { |
102 | return this.number; |
||
103 | } |
||
104 | 44977 | jjdelcerro | |
105 | 43660 | jjdelcerro | public long getLastAccess() { |
106 | return this.lastaccess; |
||
107 | } |
||
108 | 44977 | jjdelcerro | |
109 | 43660 | jjdelcerro | public int size() { |
110 | return this.size; |
||
111 | } |
||
112 | 44977 | jjdelcerro | |
113 | 43691 | jjdelcerro | public void dispose() { |
114 | for (int i = 0; i < features.length; i++) { |
||
115 | features[i] = null;
|
||
116 | } |
||
117 | this.features = null; |
||
118 | this.lastaccess = 0; |
||
119 | } |
||
120 | 44977 | jjdelcerro | } |
121 | |||
122 | 43660 | jjdelcerro | private static class PageCache { |
123 | |||
124 | private final int maxpages; |
||
125 | 43691 | jjdelcerro | private List<Page> pages; |
126 | 44977 | jjdelcerro | |
127 | 43660 | jjdelcerro | public PageCache(int maxpages) { |
128 | this.maxpages = maxpages;
|
||
129 | this.pages = new ArrayList<>(); |
||
130 | } |
||
131 | 44977 | jjdelcerro | |
132 | 43691 | jjdelcerro | public void clear() { |
133 | 44977 | jjdelcerro | pages.forEach((page) -> { |
134 | 43691 | jjdelcerro | page.dispose(); |
135 | 44977 | jjdelcerro | }); |
136 | this.pages = new ArrayList<>(); |
||
137 | 43691 | jjdelcerro | } |
138 | 44977 | jjdelcerro | |
139 | 43660 | jjdelcerro | public Page get(long pageNumber) { |
140 | 44977 | jjdelcerro | for (Page page : pages) {
|
141 | if (page.getPageNumber() == pageNumber) {
|
||
142 | 43660 | jjdelcerro | return page;
|
143 | } |
||
144 | } |
||
145 | return null; |
||
146 | } |
||
147 | 44977 | jjdelcerro | |
148 | 43660 | jjdelcerro | public void add(Page page) { |
149 | 44977 | jjdelcerro | if (this.pages.size() < this.maxpages) { |
150 | 43660 | jjdelcerro | this.pages.add(page);
|
151 | return;
|
||
152 | } |
||
153 | int toDrop = 0; |
||
154 | 44977 | jjdelcerro | for (int i = 0; i < this.pages.size(); i++) { |
155 | if (this.pages.get(i).getLastAccess() < this.pages.get(toDrop).getLastAccess()) { |
||
156 | 43660 | jjdelcerro | toDrop = i; |
157 | } |
||
158 | } |
||
159 | this.pages.set(toDrop, page);
|
||
160 | } |
||
161 | } |
||
162 | 44977 | jjdelcerro | |
163 | 40435 | jjdelcerro | private FeatureQuery query;
|
164 | |||
165 | private FeatureStore featureStore;
|
||
166 | |||
167 | 44977 | jjdelcerro | /**
|
168 | * If the selected Features must be returned as the first ones. *
|
||
169 | */
|
||
170 | 40435 | jjdelcerro | private boolean selectionUp = false; |
171 | |||
172 | private FeatureSet featSet = null; |
||
173 | |||
174 | private Feature[] features = null; |
||
175 | 43660 | jjdelcerro | private PageCache cachedPages = null; |
176 | 40435 | jjdelcerro | |
177 | 41212 | jjdelcerro | private boolean initialization_completed = false; |
178 | 42807 | jjdelcerro | |
179 | private FeatureSelection selection = null; |
||
180 | 44977 | jjdelcerro | |
181 | 40435 | jjdelcerro | /**
|
182 | * Constructs a FeaturePagingHelperImpl from data of a FeatureStore.
|
||
183 | 41819 | fdiaz | *
|
184 | 44977 | jjdelcerro | * @param featureStore to extract data from
|
185 | * @throws DataException if there is an error initializing the helper
|
||
186 | 40435 | jjdelcerro | */
|
187 | public FeaturePagingHelperImpl(FeatureStore featureStore)
|
||
188 | 44977 | jjdelcerro | throws BaseException {
|
189 | 40435 | jjdelcerro | this(featureStore, DEFAULT_PAGE_SIZE);
|
190 | } |
||
191 | |||
192 | /**
|
||
193 | * Constructs a FeaturePagingHelperImpl from data of a FeatureStore.
|
||
194 | 41819 | fdiaz | *
|
195 | 44977 | jjdelcerro | * @param featureStore to extract data from
|
196 | * @param pageSize the number of elements per page data
|
||
197 | * @throws DataException if there is an error initializing the helper
|
||
198 | 40435 | jjdelcerro | */
|
199 | public FeaturePagingHelperImpl(FeatureStore featureStore, int pageSize) |
||
200 | 44977 | jjdelcerro | throws BaseException {
|
201 | 40435 | jjdelcerro | this(featureStore, null, pageSize); |
202 | } |
||
203 | |||
204 | /**
|
||
205 | * Constructs a FeaturePagingHelperImpl from data of a FeatureStore.
|
||
206 | 41819 | fdiaz | *
|
207 | 44977 | jjdelcerro | * @param featureStore to extract data from
|
208 | * @param featureQuery
|
||
209 | * @throws DataException if there is an error initializing the helper
|
||
210 | 40435 | jjdelcerro | */
|
211 | public FeaturePagingHelperImpl(FeatureStore featureStore,
|
||
212 | 44977 | jjdelcerro | FeatureQuery featureQuery) throws BaseException {
|
213 | 40435 | jjdelcerro | this(featureStore, featureQuery, DEFAULT_PAGE_SIZE);
|
214 | } |
||
215 | |||
216 | /**
|
||
217 | * Constructs a FeaturePagingHelperImpl from data of a FeatureStore.
|
||
218 | 41819 | fdiaz | *
|
219 | 44977 | jjdelcerro | * @param featureStore
|
220 | * @param featureQuery
|
||
221 | * @param pageSize the number of elements per page data
|
||
222 | * @throws DataException if there is an error initializing the helper
|
||
223 | 40435 | jjdelcerro | */
|
224 | public FeaturePagingHelperImpl(FeatureStore featureStore,
|
||
225 | 44977 | jjdelcerro | FeatureQuery featureQuery, int pageSize) throws BaseException { |
226 | 40435 | jjdelcerro | super();
|
227 | 43660 | jjdelcerro | this.cachedPages = new PageCache(3); |
228 | 44977 | jjdelcerro | FeatureQuery theQuery = featureQuery; |
229 | 40435 | jjdelcerro | if (featureQuery == null) { |
230 | 44977 | jjdelcerro | theQuery = featureStore.createFeatureQuery(); |
231 | theQuery.setFeatureType(featureStore.getDefaultFeatureType()); |
||
232 | 40435 | jjdelcerro | } |
233 | |||
234 | this.featureStore = featureStore;
|
||
235 | 45425 | jjdelcerro | DisposeUtils.bind(this.featureStore);
|
236 | |||
237 | 44977 | jjdelcerro | this.query = theQuery;
|
238 | 40435 | jjdelcerro | this.query.setPageSize(pageSize);
|
239 | |||
240 | 44977 | jjdelcerro | setDefaultCalculator(() -> { |
241 | FeatureSet featureSet = getFeatureSet(false);
|
||
242 | try {
|
||
243 | return featureSet.getSize();
|
||
244 | } catch (BaseException e) {
|
||
245 | LOG.warn("Error getting the size of the FeatureSet: " + featureSet, e);
|
||
246 | return 0l; |
||
247 | 40435 | jjdelcerro | } |
248 | }, pageSize); |
||
249 | 40595 | jldominguez | if (LOG.isDebugEnabled()) {
|
250 | 44977 | jjdelcerro | LOG.debug("FeaturePagingHelperImpl created with {} pages, and a page size of {}",
|
251 | getCalculator().getNumPages(), pageSize |
||
252 | ); |
||
253 | 40595 | jldominguez | } |
254 | 41212 | jjdelcerro | this.initialization_completed = true; |
255 | 40435 | jjdelcerro | } |
256 | |||
257 | /**
|
||
258 | * @return the selectionUp status
|
||
259 | */
|
||
260 | 44977 | jjdelcerro | @Override
|
261 | 41630 | jjdelcerro | public boolean isSelectionUp() { |
262 | 40435 | jjdelcerro | return selectionUp;
|
263 | } |
||
264 | 44977 | jjdelcerro | |
265 | @Override
|
||
266 | 42807 | jjdelcerro | public FeatureSelection getSelection() {
|
267 | if (selection == null) { |
||
268 | try {
|
||
269 | return getFeatureStore().getFeatureSelection();
|
||
270 | } catch (Exception e) { |
||
271 | LOG.warn("Error getting the selection", e);
|
||
272 | } |
||
273 | } |
||
274 | return selection;
|
||
275 | } |
||
276 | 44977 | jjdelcerro | |
277 | @Override
|
||
278 | 42807 | jjdelcerro | public void setSelection(FeatureSelection selection) { |
279 | this.selection = selection;
|
||
280 | } |
||
281 | 44977 | jjdelcerro | |
282 | 42807 | jjdelcerro | @Override
|
283 | 40435 | jjdelcerro | public void setSelectionUp(boolean selectionUp) { |
284 | this.selectionUp = selectionUp;
|
||
285 | try {
|
||
286 | 43728 | jjdelcerro | this.cachedPages.clear();
|
287 | 42807 | jjdelcerro | FeatureSelection currentSelection = getSelection(); |
288 | 41630 | jjdelcerro | if (selectionUp && !currentSelection.isEmpty()) {
|
289 | 44977 | jjdelcerro | // initialSelection =(FeatureSelection) currentSelection.clone();
|
290 | 40435 | jjdelcerro | setCalculator(new OneSubsetOneSetPagingCalculator(
|
291 | 44977 | jjdelcerro | new FeatureSetSizeableDelegate(currentSelection),
|
292 | new FeatureSetSizeableDelegate(getFeatureSet(false)), |
||
293 | getMaxPageSize())); |
||
294 | 40435 | jjdelcerro | } else {
|
295 | setDefaultCalculator(new FeatureSetSizeableDelegate(
|
||
296 | 44977 | jjdelcerro | getFeatureSet(false)), getMaxPageSize()
|
297 | ); |
||
298 | 40435 | jjdelcerro | } |
299 | } catch (BaseException e) {
|
||
300 | 44977 | jjdelcerro | LOG.warn("Error setting the selection up setting to: " + selectionUp, e);
|
301 | 40435 | jjdelcerro | } |
302 | } |
||
303 | |||
304 | 44977 | jjdelcerro | @Override
|
305 | 42991 | jbadia | public synchronized Feature getFeatureAt(long index) throws BaseException { |
306 | 40435 | jjdelcerro | // Check if we have currently loaded the viewed page data,
|
307 | // or we need to load a new one
|
||
308 | 44977 | jjdelcerro | int maxPageSize = getMaxPageSize();
|
309 | long currentPage = getCurrentPage();
|
||
310 | long currentPage2 = currentPage;
|
||
311 | |||
312 | 42991 | jbadia | long pageForIndex = (long) Math.floor(index / maxPageSize); |
313 | 40435 | jjdelcerro | |
314 | 42991 | jbadia | if (pageForIndex != currentPage) {
|
315 | 40435 | jjdelcerro | setCurrentPage(pageForIndex); |
316 | 42991 | jbadia | currentPage2 = getCurrentPage(); |
317 | 40435 | jjdelcerro | } |
318 | |||
319 | 42991 | jbadia | long positionForIndex = index - (currentPage2 * maxPageSize);
|
320 | 40435 | jjdelcerro | |
321 | 41268 | jjdelcerro | if (positionForIndex >= getCurrentPageFeatures().length) {
|
322 | 40435 | jjdelcerro | throw new FeatureIndexException( |
323 | 44977 | jjdelcerro | new IndexOutOfBoundsException("positionForIndex too big: " |
324 | + positionForIndex)); |
||
325 | 40435 | jjdelcerro | } else {
|
326 | 41268 | jjdelcerro | Feature feature = getCurrentPageFeatures()[(int) positionForIndex];
|
327 | 41212 | jjdelcerro | return feature;
|
328 | 40435 | jjdelcerro | } |
329 | 41819 | fdiaz | |
330 | 40435 | jjdelcerro | } |
331 | |||
332 | 44977 | jjdelcerro | @Override
|
333 | 40435 | jjdelcerro | public Feature[] getCurrentPageFeatures() { |
334 | 44977 | jjdelcerro | if (this.features == null) { |
335 | 41268 | jjdelcerro | try {
|
336 | this.loadCurrentPageData();
|
||
337 | } catch (BaseException ex) {
|
||
338 | // Do nothing
|
||
339 | } |
||
340 | 44977 | jjdelcerro | if (this.features == null) { |
341 | 41268 | jjdelcerro | String msg = "Can't retrieve the features from current page."; |
342 | LOG.warn(msg); |
||
343 | throw new RuntimeException(msg); |
||
344 | } |
||
345 | } |
||
346 | 40435 | jjdelcerro | return features;
|
347 | } |
||
348 | 44977 | jjdelcerro | |
349 | 44794 | omartinez | @Override
|
350 | public FeatureSet getFeatureSet() {
|
||
351 | return this.getFeatureSet(false); |
||
352 | } |
||
353 | 40435 | jjdelcerro | |
354 | /**
|
||
355 | 44977 | jjdelcerro | * Gets the feature set. The boolean tells whether we must create the
|
356 | * featureset again (for example perhaps we need it after a feature has been
|
||
357 | * added/removed)
|
||
358 | 40435 | jjdelcerro | */
|
359 | private FeatureSet getFeatureSet(boolean reset) { |
||
360 | 41819 | fdiaz | |
361 | 40435 | jjdelcerro | if (featSet == null || reset) { |
362 | 41819 | fdiaz | |
363 | 40435 | jjdelcerro | if (featSet != null) { |
364 | try {
|
||
365 | featSet.dispose(); |
||
366 | } catch (Exception ex) { |
||
367 | LOG.info("Error while disposing featset.", ex);
|
||
368 | } |
||
369 | } |
||
370 | 41819 | fdiaz | |
371 | 40435 | jjdelcerro | try {
|
372 | 41819 | fdiaz | FeatureStore featureStore = getFeatureStore(); |
373 | 40435 | jjdelcerro | synchronized (featureStore) {
|
374 | 41819 | fdiaz | featSet = featureStore.getFeatureSet(getFeatureQuery()); |
375 | 40435 | jjdelcerro | } |
376 | } catch (DataException e) {
|
||
377 | throw new RuntimeException("Error getting a feature set with the query " + getFeatureQuery()); |
||
378 | } |
||
379 | } |
||
380 | return featSet;
|
||
381 | } |
||
382 | 41819 | fdiaz | |
383 | 43691 | jjdelcerro | @Override
|
384 | 40435 | jjdelcerro | public DynObjectSet getDynObjectSet() {
|
385 | 44977 | jjdelcerro | return getFeatureSet(false).getDynObjectSet(); |
386 | 40435 | jjdelcerro | } |
387 | |||
388 | 43691 | jjdelcerro | @Override
|
389 | 40435 | jjdelcerro | public void reloadCurrentPage() throws BaseException { |
390 | boolean sel_up = this.isSelectionUp(); |
||
391 | 44977 | jjdelcerro | try {
|
392 | setSelectionUp(false);
|
||
393 | if (getCalculator().getCurrentPage() > -1) { |
||
394 | this.cachedPages.clear();
|
||
395 | loadCurrentPageData(); |
||
396 | } |
||
397 | } finally {
|
||
398 | if (sel_up) {
|
||
399 | setSelectionUp(true);
|
||
400 | } |
||
401 | 40435 | jjdelcerro | } |
402 | } |
||
403 | |||
404 | 43691 | jjdelcerro | @Override
|
405 | 40435 | jjdelcerro | public void reload() throws BaseException { |
406 | 41819 | fdiaz | |
407 | 43726 | jjdelcerro | this.cachedPages.clear();
|
408 | 40435 | jjdelcerro | /*
|
409 | * Force re-creation of feature set
|
||
410 | */
|
||
411 | this.getFeatureSet(true); |
||
412 | |||
413 | 44977 | jjdelcerro | setDefaultCalculator(() -> { |
414 | FeatureSet featureSet = getFeatureSet(false);
|
||
415 | try {
|
||
416 | return featureSet.getSize();
|
||
417 | } catch (BaseException e) {
|
||
418 | LOG.warn("Error getting the size of the FeatureSet: "+ featureSet, e);
|
||
419 | return 0l; |
||
420 | 40435 | jjdelcerro | } |
421 | }, getCalculator().getMaxPageSize()); |
||
422 | 45154 | jjdelcerro | // reloadCurrentPage();
|
423 | 40435 | jjdelcerro | } |
424 | |||
425 | 44977 | jjdelcerro | @Override
|
426 | 40435 | jjdelcerro | public FeatureStore getFeatureStore() {
|
427 | return featureStore;
|
||
428 | } |
||
429 | |||
430 | 44977 | jjdelcerro | @Override
|
431 | 40435 | jjdelcerro | public FeatureQuery getFeatureQuery() {
|
432 | return query;
|
||
433 | } |
||
434 | |||
435 | /**
|
||
436 | * Loads all the Features of the current page.
|
||
437 | 44977 | jjdelcerro | *
|
438 | 43660 | jjdelcerro | * @throws org.gvsig.tools.exception.BaseException
|
439 | 40435 | jjdelcerro | */
|
440 | 43660 | jjdelcerro | @Override
|
441 | 42991 | jbadia | protected synchronized void loadCurrentPageData() throws BaseException { |
442 | 44977 | jjdelcerro | if (!initialization_completed) {
|
443 | 41212 | jjdelcerro | return;
|
444 | } |
||
445 | 40435 | jjdelcerro | final int currentPageSize = getCalculator().getCurrentPageSize(); |
446 | 43660 | jjdelcerro | final long currentPage = getCalculator().getCurrentPage(); |
447 | Page page = this.cachedPages.get(currentPage);
|
||
448 | 44977 | jjdelcerro | if (page == null) { |
449 | 43660 | jjdelcerro | page = new Page(currentPage, currentPageSize);
|
450 | 40435 | jjdelcerro | |
451 | 43660 | jjdelcerro | long t1 = 0; |
452 | if (LOG.isTraceEnabled()) {
|
||
453 | t1 = System.currentTimeMillis();
|
||
454 | } |
||
455 | 40435 | jjdelcerro | |
456 | 43660 | jjdelcerro | if (selectionUp) {
|
457 | loadCurrentPageDataWithSelectionUp(page); |
||
458 | } else {
|
||
459 | loadCurrentPageDataNoSelection(page); |
||
460 | } |
||
461 | 40435 | jjdelcerro | |
462 | 43660 | jjdelcerro | if (LOG.isTraceEnabled()) {
|
463 | long t2 = System.currentTimeMillis(); |
||
464 | LOG.trace("Time to load {} features: {} ms", currentPageSize, t2 - t1);
|
||
465 | } |
||
466 | this.cachedPages.add(page);
|
||
467 | 40435 | jjdelcerro | } |
468 | 43660 | jjdelcerro | this.features = page.getFeatures();
|
469 | 40435 | jjdelcerro | } |
470 | 41819 | fdiaz | |
471 | 43660 | jjdelcerro | private void loadCurrentPageDataWithSelectionUp(final Page page) |
472 | 41630 | jjdelcerro | throws BaseException {
|
473 | 44977 | jjdelcerro | FeatureSelection theSelection = getSelection(); |
474 | if (theSelection == null) { |
||
475 | 43660 | jjdelcerro | loadCurrentPageDataNoSelection(page); |
476 | 41630 | jjdelcerro | } else {
|
477 | FeatureSet set = getFeatureSet(false);
|
||
478 | try {
|
||
479 | OneSubsetOneSetPagingCalculator twoSetsCalculator = null;
|
||
480 | if (getCalculator() instanceof OneSubsetOneSetPagingCalculator) { |
||
481 | 44977 | jjdelcerro | twoSetsCalculator = (OneSubsetOneSetPagingCalculator) getCalculator(); |
482 | 41630 | jjdelcerro | } else {
|
483 | 44977 | jjdelcerro | twoSetsCalculator = new OneSubsetOneSetPagingCalculator(
|
484 | new FeatureSetSizeableDelegate(theSelection),
|
||
485 | 41630 | jjdelcerro | new FeatureSetSizeableDelegate(set),
|
486 | 44977 | jjdelcerro | getMaxPageSize(), getCalculator().getCurrentPage() |
487 | ); |
||
488 | 41630 | jjdelcerro | setCalculator(twoSetsCalculator); |
489 | } |
||
490 | 44977 | jjdelcerro | // First load values from the selection, if the current page has
|
491 | 41630 | jjdelcerro | // elements from it
|
492 | if (twoSetsCalculator.hasCurrentPageAnyValuesInFirstSet()) {
|
||
493 | 44977 | jjdelcerro | loadDataFromFeatureSet(page, 0, theSelection,
|
494 | 41630 | jjdelcerro | twoSetsCalculator.getFirstSetInitialIndex(), |
495 | 44977 | jjdelcerro | twoSetsCalculator.getFirstSetHowMany(), null
|
496 | ); |
||
497 | 41630 | jjdelcerro | } |
498 | 44977 | jjdelcerro | // Next, load values from the FeatureSet if the current page has values
|
499 | 41630 | jjdelcerro | // from it
|
500 | if (twoSetsCalculator.hasCurrentPageAnyValuesInSecondSet()) {
|
||
501 | loadDataFromFeatureSet( |
||
502 | 43660 | jjdelcerro | page, |
503 | 41630 | jjdelcerro | // The cast will work as that size will be <= maxpagesize,
|
504 | // which is an int
|
||
505 | (int) twoSetsCalculator.getFirstSetHowMany(), set,
|
||
506 | twoSetsCalculator.getSecondSetInitialIndex(), |
||
507 | 44977 | jjdelcerro | twoSetsCalculator.getSecondSetHowMany(), theSelection |
508 | ); |
||
509 | 41630 | jjdelcerro | } |
510 | } finally {
|
||
511 | 44977 | jjdelcerro | // This is the feature set we dont want to lose it
|
512 | 41630 | jjdelcerro | // set.dispose();
|
513 | } |
||
514 | 40435 | jjdelcerro | } |
515 | } |
||
516 | |||
517 | 43660 | jjdelcerro | private void loadCurrentPageDataNoSelection(final Page page) |
518 | 44977 | jjdelcerro | throws BaseException {
|
519 | 40435 | jjdelcerro | |
520 | long firstPosition = getCalculator().getInitialIndex();
|
||
521 | |||
522 | if (LOG.isDebugEnabled()) {
|
||
523 | 44977 | jjdelcerro | LOG.debug("Loading {} Features starting at position {}",
|
524 | getCalculator().getCurrentPageSize(), firstPosition |
||
525 | 43660 | jjdelcerro | ); |
526 | 40435 | jjdelcerro | } |
527 | |||
528 | FeatureSet featureSet = getFeatureSet(false);
|
||
529 | try {
|
||
530 | 44977 | jjdelcerro | loadDataFromFeatureSet(page, 0, featureSet, firstPosition,
|
531 | getCalculator().getCurrentPageSize(), null);
|
||
532 | } catch (DataException ex) {
|
||
533 | 40435 | jjdelcerro | throw ex;
|
534 | 44977 | jjdelcerro | } finally {
|
535 | // This is the feature set we dont want to lose it
|
||
536 | // featureSet.dispose();
|
||
537 | 40435 | jjdelcerro | } |
538 | } |
||
539 | |||
540 | 43660 | jjdelcerro | private void loadDataFromFeatureSet(final Page page, |
541 | 44977 | jjdelcerro | final int valuesPosition, FeatureSet set, long initialIndex, |
542 | final long howMany, final FeatureSelection selectedFeaturesToSkip) |
||
543 | throws DataException {
|
||
544 | 40435 | jjdelcerro | |
545 | try {
|
||
546 | 44840 | jjdelcerro | final MutableBoolean errorReported = new MutableBoolean(false); |
547 | 40435 | jjdelcerro | set.accept(new Visitor() {
|
548 | private int i = valuesPosition; |
||
549 | |||
550 | 43660 | jjdelcerro | @Override
|
551 | 40435 | jjdelcerro | public void visit(Object obj) throws VisitCanceledException, |
552 | 44977 | jjdelcerro | BaseException { |
553 | 40435 | jjdelcerro | if (i >= valuesPosition + howMany) {
|
554 | throw new VisitCanceledException(); |
||
555 | } |
||
556 | Feature current = (Feature) obj; |
||
557 | // Add the current Feature only if we don't skip selected
|
||
558 | // features or the feature is not selected
|
||
559 | if (selectedFeaturesToSkip == null |
||
560 | 44977 | jjdelcerro | || !selectedFeaturesToSkip.isSelected(current)) { |
561 | 41630 | jjdelcerro | try {
|
562 | 44977 | jjdelcerro | page.setFeature(i, current.getCopy()); |
563 | 41630 | jjdelcerro | i++; |
564 | 44977 | jjdelcerro | } catch (Exception ex) { |
565 | 41630 | jjdelcerro | // Aqui no deberia petar, pero...
|
566 | // me he encontrado un caso que tenia una referencia a
|
||
567 | 41819 | fdiaz | // una feature seleccionada que ya no existia. No se como
|
568 | 41630 | jjdelcerro | // habia pasado, se habia quedado de antes guardada en el
|
569 | // proyecto pero la feature ya no existia, y eso hacia que
|
||
570 | // petase al intentar leer de disco la feature a partir
|
||
571 | // de una referencia no valida.
|
||
572 | 44977 | jjdelcerro | if (!errorReported.booleanValue()) {
|
573 | // Solo sacamos un error por pagina de datos.
|
||
574 | LOG.warn("Problemas recuperando feature.", ex);
|
||
575 | errorReported.setTrue(); |
||
576 | 44840 | jjdelcerro | } |
577 | 41630 | jjdelcerro | } |
578 | 40435 | jjdelcerro | } |
579 | } |
||
580 | 43358 | jjdelcerro | }, initialIndex, howMany); |
581 | 44977 | jjdelcerro | } catch (VisitCanceledException ex) {
|
582 | 43358 | jjdelcerro | // Do nothing
|
583 | 40435 | jjdelcerro | } catch (BaseException e) {
|
584 | if (e instanceof DataException) { |
||
585 | throw ((DataException) e);
|
||
586 | } else {
|
||
587 | 44977 | jjdelcerro | LOG.warn("Error loading the data starting at position {}", initialIndex, e);
|
588 | 40435 | jjdelcerro | } |
589 | } |
||
590 | } |
||
591 | |||
592 | 44977 | jjdelcerro | @Override
|
593 | 40435 | jjdelcerro | public void delete(Feature feature) throws BaseException { |
594 | featureStore.delete(feature); |
||
595 | /*
|
||
596 | * Force re-creation of feature set
|
||
597 | */
|
||
598 | this.getFeatureSet(true); |
||
599 | |||
600 | reloadCurrentPage(); |
||
601 | } |
||
602 | |||
603 | 44977 | jjdelcerro | @Override
|
604 | 40435 | jjdelcerro | public void insert(EditableFeature feature) throws BaseException { |
605 | 44977 | jjdelcerro | featureStore.insert(feature); |
606 | 40435 | jjdelcerro | /*
|
607 | * Force re-creation of feature set
|
||
608 | */
|
||
609 | this.getFeatureSet(true); |
||
610 | |||
611 | reloadCurrentPage(); |
||
612 | } |
||
613 | 44977 | jjdelcerro | |
614 | @Override
|
||
615 | 44488 | jjdelcerro | public boolean isEmpty() { |
616 | try {
|
||
617 | return getFeatureSet(false).isEmpty(); |
||
618 | } catch (ConcurrentDataModificationException ex) {
|
||
619 | LOG.warn("ConcurrentDataModification error asking about the emptiness of the list. Retrying reloading data.");
|
||
620 | try {
|
||
621 | reload(); |
||
622 | } catch (BaseException e) {
|
||
623 | LOG.warn("Error reloading data.", e);
|
||
624 | throw new RuntimeException(e); |
||
625 | } |
||
626 | try {
|
||
627 | return getFeatureSet(false).isEmpty(); |
||
628 | 45425 | jjdelcerro | } catch (RuntimeException e) { |
629 | throw e;
|
||
630 | } catch (Exception e) { |
||
631 | 44977 | jjdelcerro | LOG.warn("Error asking about the emptiness of the list after reloading data.", e);
|
632 | 44488 | jjdelcerro | throw new RuntimeException(e); |
633 | } |
||
634 | 45425 | jjdelcerro | } catch (Exception ex) { |
635 | 44977 | jjdelcerro | throw new RuntimeException(ex); |
636 | 44488 | jjdelcerro | } |
637 | } |
||
638 | 40435 | jjdelcerro | |
639 | 44977 | jjdelcerro | @Override
|
640 | 40435 | jjdelcerro | public void update(EditableFeature feature) throws BaseException { |
641 | 44977 | jjdelcerro | featureStore.update(feature); |
642 | 40435 | jjdelcerro | /*
|
643 | * Force re-creation of feature set
|
||
644 | */
|
||
645 | this.getFeatureSet(true); |
||
646 | |||
647 | reloadCurrentPage(); |
||
648 | } |
||
649 | |||
650 | 44977 | jjdelcerro | @Override
|
651 | 40435 | jjdelcerro | public FeatureType getFeatureType() {
|
652 | 41819 | fdiaz | |
653 | 40435 | jjdelcerro | FeatureType ft = null;
|
654 | 41819 | fdiaz | |
655 | 40435 | jjdelcerro | try {
|
656 | ft = featureStore.getDefaultFeatureType(); |
||
657 | } catch (DataException e) {
|
||
658 | 44977 | jjdelcerro | LOG.warn("Error while getting feature type: "+ e.getMessage(), e);
|
659 | 40435 | jjdelcerro | } |
660 | return ft;
|
||
661 | } |
||
662 | |||
663 | 44977 | jjdelcerro | @Override
|
664 | 40435 | jjdelcerro | protected void doDispose() throws BaseException { |
665 | if (featSet != null) { |
||
666 | try {
|
||
667 | featSet.dispose(); |
||
668 | } catch (Exception ex) { |
||
669 | LOG.info("Error while disposing featset.", ex);
|
||
670 | } |
||
671 | } |
||
672 | } |
||
673 | |||
674 | 44977 | jjdelcerro | @Override
|
675 | 40435 | jjdelcerro | public DynObject[] getCurrentPageDynObjects() { |
676 | 44977 | jjdelcerro | Feature[] theFeatures = getCurrentPageFeatures();
|
677 | DynObject[] dynobjects = new DynObject[theFeatures.length]; |
||
678 | 40435 | jjdelcerro | for (int i = 0; i < dynobjects.length; i++) { |
679 | 44977 | jjdelcerro | dynobjects[i] = new DynObjectFeatureFacade(theFeatures[i]);
|
680 | 40435 | jjdelcerro | } |
681 | return dynobjects;
|
||
682 | } |
||
683 | |||
684 | 44253 | jjdelcerro | @Override
|
685 | 40435 | jjdelcerro | public DynObject getDynObjectAt(long index) throws BaseException { |
686 | return new DynObjectFeatureFacade(getFeatureAt(index)); |
||
687 | } |
||
688 | |||
689 | 44253 | jjdelcerro | @Override
|
690 | 41212 | jjdelcerro | public List asList() { |
691 | return new FeaturePagingHelperList(); |
||
692 | } |
||
693 | 41819 | fdiaz | |
694 | 44253 | jjdelcerro | @Override
|
695 | 41212 | jjdelcerro | public List asListOfDynObjects() { |
696 | return new DynObjectPagingHelperList(); |
||
697 | 41819 | fdiaz | } |
698 | |||
699 | 41212 | jjdelcerro | private class FeaturePagingHelperList extends PagingHelperList { |
700 | 44977 | jjdelcerro | |
701 | 44253 | jjdelcerro | @Override
|
702 | 41212 | jjdelcerro | public Object get(int i) { |
703 | 44253 | jjdelcerro | return this.get64(i); |
704 | } |
||
705 | |||
706 | @Override
|
||
707 | public Object get64(long i) { |
||
708 | 41212 | jjdelcerro | try {
|
709 | return getFeatureAt(i);
|
||
710 | 44253 | jjdelcerro | } catch (ConcurrentDataModificationException ex) {
|
711 | 44977 | jjdelcerro | LOG.warn("ConcurrentDataModification error getting feature " + i + " of the list. Retrying reloading data."); |
712 | 44253 | jjdelcerro | try {
|
713 | reload(); |
||
714 | } catch (BaseException e) {
|
||
715 | LOG.warn("Error reloading data.", e);
|
||
716 | throw new RuntimeException(e); |
||
717 | } |
||
718 | try {
|
||
719 | return getFeatureAt(i);
|
||
720 | } catch (Exception e) { |
||
721 | 44977 | jjdelcerro | LOG.warn("Error getting feature " + i + " of the list after reloading data.", e); |
722 | 44253 | jjdelcerro | throw new RuntimeException(e); |
723 | } |
||
724 | 41212 | jjdelcerro | } catch (BaseException ex) {
|
725 | 44977 | jjdelcerro | throw new RuntimeException(ex); |
726 | 41212 | jjdelcerro | } |
727 | } |
||
728 | 44253 | jjdelcerro | |
729 | @Override
|
||
730 | public Object set(int i, Object e) { |
||
731 | return super.set(i, e); |
||
732 | } |
||
733 | |||
734 | @Override
|
||
735 | public Object remove(int i) { |
||
736 | return super.remove(i); |
||
737 | } |
||
738 | |||
739 | @Override
|
||
740 | public boolean add(Object e) { |
||
741 | return super.add(e); |
||
742 | } |
||
743 | 41212 | jjdelcerro | } |
744 | 41819 | fdiaz | |
745 | 41212 | jjdelcerro | private class DynObjectPagingHelperList extends PagingHelperList { |
746 | 44977 | jjdelcerro | |
747 | 44253 | jjdelcerro | @Override
|
748 | 41212 | jjdelcerro | public Object get(int i) { |
749 | 44253 | jjdelcerro | return this.get64(i); |
750 | } |
||
751 | |||
752 | @Override
|
||
753 | public Object get64(long position) { |
||
754 | 41212 | jjdelcerro | try {
|
755 | 44253 | jjdelcerro | return getDynObjectAt(position);
|
756 | } catch (ConcurrentDataModificationException ex) {
|
||
757 | 44977 | jjdelcerro | LOG.warn("ConcurrentDataModification error getting element " + position + " of the list. Retrying reloading data."); |
758 | 44253 | jjdelcerro | try {
|
759 | reload(); |
||
760 | } catch (BaseException e) {
|
||
761 | LOG.warn("Error reloading data.", e);
|
||
762 | throw new RuntimeException(e); |
||
763 | } |
||
764 | try {
|
||
765 | return getDynObjectAt(position);
|
||
766 | } catch (Exception e) { |
||
767 | 44977 | jjdelcerro | LOG.warn("Error getting element " + position + " of the list after reloading data.", e); |
768 | 44253 | jjdelcerro | throw new RuntimeException(e); |
769 | } |
||
770 | 41212 | jjdelcerro | } catch (BaseException ex) {
|
771 | 44977 | jjdelcerro | throw new RuntimeException(ex); |
772 | 41212 | jjdelcerro | } |
773 | } |
||
774 | 42775 | jjdelcerro | |
775 | 41212 | jjdelcerro | } |
776 | 41819 | fdiaz | |
777 | 45196 | jjdelcerro | private abstract class PagingHelperList implements List, FacadeOfAFeaturePagingHelper, UnmodifiableBasicList, UnmodifiableBasicList64, Disposable { |
778 | 41212 | jjdelcerro | |
779 | 42775 | jjdelcerro | @Override
|
780 | 45196 | jjdelcerro | public void dispose() { |
781 | FeaturePagingHelperImpl.this.dispose(); |
||
782 | } |
||
783 | |||
784 | @Override
|
||
785 | 42775 | jjdelcerro | public FeaturePagingHelper getFeaturePagingHelper() {
|
786 | return FeaturePagingHelperImpl.this;
|
||
787 | } |
||
788 | 44253 | jjdelcerro | |
789 | @Override
|
||
790 | public String toString() { |
||
791 | return String.format("..(%d %ss)...", this.size(), featureStore.getName()); |
||
792 | } |
||
793 | 44977 | jjdelcerro | |
794 | 44253 | jjdelcerro | @Override
|
795 | public long size64() { |
||
796 | 45195 | omartinez | FeatureSet fset = null;
|
797 | 41212 | jjdelcerro | try {
|
798 | 45195 | omartinez | fset = getFeatureSet(false);
|
799 | return fset.getSize();
|
||
800 | 44253 | jjdelcerro | } catch (ConcurrentDataModificationException ex) {
|
801 | LOG.warn("ConcurrentDataModification error asking the size of the list. Retrying reloading data.");
|
||
802 | try {
|
||
803 | reload(); |
||
804 | } catch (BaseException e) {
|
||
805 | LOG.warn("Error reloading data.", e);
|
||
806 | throw new RuntimeException(e); |
||
807 | } |
||
808 | try {
|
||
809 | 45195 | omartinez | fset = getFeatureSet(false);
|
810 | return fset.getSize();
|
||
811 | 44253 | jjdelcerro | } catch (DataException e) {
|
812 | 44977 | jjdelcerro | LOG.warn("Error asking the size of the list after reloading data.", e);
|
813 | 44253 | jjdelcerro | throw new RuntimeException(e); |
814 | } |
||
815 | 41212 | jjdelcerro | } catch (DataException ex) {
|
816 | 44977 | jjdelcerro | throw new RuntimeException(ex); |
817 | 41212 | jjdelcerro | } |
818 | } |
||
819 | |||
820 | 44253 | jjdelcerro | @Override
|
821 | public int size() { |
||
822 | long sz = this.size64(); |
||
823 | 44977 | jjdelcerro | if (sz > Integer.MAX_VALUE) { |
824 | 44253 | jjdelcerro | sz = Integer.MAX_VALUE;
|
825 | } |
||
826 | return (int) sz; |
||
827 | } |
||
828 | |||
829 | @Override
|
||
830 | 41212 | jjdelcerro | public boolean isEmpty() { |
831 | try {
|
||
832 | return getFeatureSet(false).isEmpty(); |
||
833 | 41819 | fdiaz | } catch (ConcurrentDataModificationException ex) {
|
834 | 44253 | jjdelcerro | LOG.warn("ConcurrentDataModification error asking about the emptiness of the list. Retrying reloading data.");
|
835 | 41819 | fdiaz | try {
|
836 | reload(); |
||
837 | } catch (BaseException e) {
|
||
838 | LOG.warn("Error reloading data.", e);
|
||
839 | throw new RuntimeException(e); |
||
840 | } |
||
841 | try {
|
||
842 | return getFeatureSet(false).isEmpty(); |
||
843 | 45425 | jjdelcerro | } catch (RuntimeException e) { |
844 | throw e;
|
||
845 | } catch (Exception e) { |
||
846 | 44977 | jjdelcerro | LOG.warn("Error asking about the emptiness of the list after reloading data.", e);
|
847 | 41819 | fdiaz | throw new RuntimeException(e); |
848 | } |
||
849 | 45425 | jjdelcerro | } catch (RuntimeException ex) { |
850 | throw ex;
|
||
851 | } catch (Exception ex) { |
||
852 | 44977 | jjdelcerro | throw new RuntimeException(ex); |
853 | 41212 | jjdelcerro | } |
854 | } |
||
855 | |||
856 | 44253 | jjdelcerro | @Override
|
857 | 41212 | jjdelcerro | public Iterator iterator() { |
858 | try {
|
||
859 | return getFeatureSet(false).fastIterator(); |
||
860 | 44253 | jjdelcerro | } catch (ConcurrentDataModificationException ex) {
|
861 | LOG.warn("ConcurrentDataModification error getting iterator of the list. Retrying reloading data.");
|
||
862 | try {
|
||
863 | reload(); |
||
864 | } catch (BaseException e) {
|
||
865 | LOG.warn("Error reloading data.", e);
|
||
866 | throw new RuntimeException(e); |
||
867 | } |
||
868 | try {
|
||
869 | return getFeatureSet(false).fastIterator(); |
||
870 | } catch (DataException e) {
|
||
871 | 44977 | jjdelcerro | LOG.warn("Error getting iterator of the list after reloading data.", e);
|
872 | 44253 | jjdelcerro | throw new RuntimeException(e); |
873 | } |
||
874 | 41212 | jjdelcerro | } catch (DataException ex) {
|
875 | 44977 | jjdelcerro | throw new RuntimeException(ex); |
876 | 41212 | jjdelcerro | } |
877 | } |
||
878 | |||
879 | 44253 | jjdelcerro | @Override
|
880 | 41212 | jjdelcerro | public boolean contains(Object o) { |
881 | throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. |
||
882 | } |
||
883 | |||
884 | 44253 | jjdelcerro | @Override
|
885 | 41212 | jjdelcerro | public Object[] toArray() { |
886 | throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. |
||
887 | } |
||
888 | |||
889 | 44253 | jjdelcerro | @Override
|
890 | 41212 | jjdelcerro | public Object[] toArray(Object[] ts) { |
891 | throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. |
||
892 | } |
||
893 | |||
894 | 44253 | jjdelcerro | @Override
|
895 | 41212 | jjdelcerro | public boolean add(Object e) { |
896 | throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. |
||
897 | } |
||
898 | |||
899 | 44253 | jjdelcerro | @Override
|
900 | 41212 | jjdelcerro | public boolean remove(Object o) { |
901 | throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. |
||
902 | } |
||
903 | |||
904 | 44253 | jjdelcerro | @Override
|
905 | 41212 | jjdelcerro | public boolean containsAll(Collection clctn) { |
906 | throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. |
||
907 | } |
||
908 | |||
909 | 44253 | jjdelcerro | @Override
|
910 | 41212 | jjdelcerro | public boolean addAll(Collection clctn) { |
911 | throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. |
||
912 | } |
||
913 | |||
914 | 44253 | jjdelcerro | @Override
|
915 | 41212 | jjdelcerro | public boolean addAll(int i, Collection clctn) { |
916 | throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. |
||
917 | } |
||
918 | |||
919 | 44253 | jjdelcerro | @Override
|
920 | 41212 | jjdelcerro | public boolean removeAll(Collection clctn) { |
921 | throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. |
||
922 | } |
||
923 | |||
924 | 44253 | jjdelcerro | @Override
|
925 | 41212 | jjdelcerro | public boolean retainAll(Collection clctn) { |
926 | throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. |
||
927 | } |
||
928 | |||
929 | 44253 | jjdelcerro | @Override
|
930 | 41212 | jjdelcerro | public void clear() { |
931 | throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. |
||
932 | } |
||
933 | |||
934 | 44253 | jjdelcerro | @Override
|
935 | 41212 | jjdelcerro | public Object set(int i, Object e) { |
936 | throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. |
||
937 | } |
||
938 | |||
939 | 44253 | jjdelcerro | @Override
|
940 | 41212 | jjdelcerro | public void add(int i, Object e) { |
941 | throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. |
||
942 | } |
||
943 | |||
944 | 44253 | jjdelcerro | @Override
|
945 | 41212 | jjdelcerro | public Object remove(int i) { |
946 | throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. |
||
947 | } |
||
948 | |||
949 | 44253 | jjdelcerro | @Override
|
950 | 41212 | jjdelcerro | public int indexOf(Object o) { |
951 | throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. |
||
952 | } |
||
953 | |||
954 | 44253 | jjdelcerro | @Override
|
955 | 41212 | jjdelcerro | public int lastIndexOf(Object o) { |
956 | throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. |
||
957 | } |
||
958 | |||
959 | 44253 | jjdelcerro | @Override
|
960 | 41212 | jjdelcerro | public ListIterator listIterator() { |
961 | throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. |
||
962 | } |
||
963 | |||
964 | 44253 | jjdelcerro | @Override
|
965 | 41212 | jjdelcerro | public ListIterator listIterator(int i) { |
966 | throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. |
||
967 | } |
||
968 | |||
969 | 44253 | jjdelcerro | @Override
|
970 | 41212 | jjdelcerro | public List subList(int i, int i1) { |
971 | throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. |
||
972 | } |
||
973 | 41819 | fdiaz | |
974 | 44253 | jjdelcerro | @Override
|
975 | public List toList() { |
||
976 | return this; |
||
977 | } |
||
978 | |||
979 | 41212 | jjdelcerro | } |
980 | 45425 | jjdelcerro | |
981 | @Override
|
||
982 | public long size64() { |
||
983 | return this.getTotalSize(); |
||
984 | } |
||
985 | |||
986 | @Override
|
||
987 | public Feature get64(long position) { |
||
988 | try {
|
||
989 | return this.getFeatureAt(position); |
||
990 | } catch (BaseException ex) {
|
||
991 | throw new RuntimeException(ex); |
||
992 | } |
||
993 | } |
||
994 | |||
995 | @Override
|
||
996 | public Iterator<Feature> iterator() { |
||
997 | try {
|
||
998 | return getFeatureSet(false).fastIterator(); |
||
999 | } catch (Exception ex) { |
||
1000 | throw new RuntimeException(ex); |
||
1001 | } |
||
1002 | } |
||
1003 | |||
1004 | 40435 | jjdelcerro | } |