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