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