Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.compat.cdc / org.gvsig.fmap.dal / org.gvsig.fmap.dal.impl / src / main / java / org / gvsig / fmap / dal / feature / impl / LargeFeatureReferenceSelection.java @ 47248

History | View | Annotate | Download (13.2 KB)

1 45426 fdiaz
/*
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright (C) 2007-2020 gvSIG Association.
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 3
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program. If not, see <https://www.gnu.org/licenses/>.
18
 *
19
 * For any additional information, do not hesitate to contact us
20
 * at info AT gvsig.com, or visit our website www.gvsig.com.
21
 */
22
package org.gvsig.fmap.dal.feature.impl;
23
24
import java.util.Iterator;
25
import java.util.List;
26
import java.util.Set;
27
import org.gvsig.fmap.dal.DataStore;
28
import org.gvsig.fmap.dal.DataStoreNotification;
29
import org.gvsig.fmap.dal.exception.DataException;
30
import org.gvsig.fmap.dal.feature.Feature;
31
import org.gvsig.fmap.dal.feature.FeatureReference;
32
import org.gvsig.fmap.dal.feature.FeatureReferenceSelection;
33
import org.gvsig.fmap.dal.feature.FeatureStore;
34
import org.gvsig.fmap.dal.feature.FeatureStoreNotification;
35
import org.gvsig.fmap.dal.feature.FeatureType;
36
import org.gvsig.tools.ToolsLocator;
37
import org.gvsig.tools.dispose.DisposeUtils;
38
import org.gvsig.tools.dispose.impl.AbstractDisposable;
39
import org.gvsig.tools.dynobject.DynStruct;
40
import org.gvsig.tools.exception.BaseException;
41
import org.gvsig.tools.observer.Observable;
42
import org.gvsig.tools.observer.Observer;
43
import org.gvsig.tools.observer.impl.DelegateWeakReferencingObservable;
44
import org.gvsig.tools.persistence.PersistentState;
45
import org.gvsig.tools.persistence.exception.PersistenceException;
46 45469 jjdelcerro
import org.gvsig.tools.util.Size64;
47 45426 fdiaz
import org.gvsig.tools.visitor.Visitor;
48
49
/**
50
 *
51
 * @author gvSIG Team
52
 */
53 45469 jjdelcerro
@SuppressWarnings("UseSpecificCatch")
54 45426 fdiaz
public class LargeFeatureReferenceSelection extends AbstractDisposable
55
        implements FeatureReferenceSelection {
56
57
        public static final String DYNCLASS_PERSISTENT_NAME = "LargeFeatureReferenceSelection";
58
59
    private Set<String> selection;
60 45469 jjdelcerro
    private DefaultFeatureStore featureStore;
61 45426 fdiaz
    private Boolean available = null;
62
    private DelegateWeakReferencingObservable delegateObservable
63
            = new DelegateWeakReferencingObservable(this);
64
65
    public LargeFeatureReferenceSelection(DefaultFeatureStore featureStore) {
66
        super();
67
        this.featureStore = featureStore;
68
        DisposeUtils.bind(this.featureStore);
69 45469 jjdelcerro
        this.selection = featureStore.getManager().createLargeSet();
70 45426 fdiaz
71
    }
72
73
    LargeFeatureReferenceSelection(FeatureStore featureStore, FeatureSelectionHelper helper) {
74
        super();
75 45469 jjdelcerro
        this.featureStore = (DefaultFeatureStore) featureStore;
76 45426 fdiaz
        DisposeUtils.bind(this.featureStore);
77 45469 jjdelcerro
        this.selection = this.featureStore.getManager().createLargeSet();
78 45426 fdiaz
    }
79
80
    /**
81
     * Constructor used by the persistence manager. Don't use directly. After to
82
     * invoke this method, the persistence manager calls the the method
83
     * {@link #loadFromState(PersistentState)} to set the values of the internal
84
     * attributes that this class needs to work.
85
     */
86
    LargeFeatureReferenceSelection() {
87
        super();
88
    }
89
90
    public FeatureStore getFeatureStore() {
91
        return featureStore;
92
    }
93
94
    @Override
95
    public boolean select(FeatureReference reference) {
96
        return this.selection.add(reference.getCode());
97
    }
98
99
    @Override
100
    public boolean deselect(FeatureReference reference) {
101
        boolean change;
102
        change = this.selection.contains(reference.getCode());
103
        this.selection.remove(reference.getCode());
104
        if (change) {
105
            notifyObservers(DataStoreNotification.SELECTION_CHANGE);
106
        }
107
        return change;
108
    }
109
110
    @Override
111
    public void selectAll() throws DataException {
112
        try {
113
            this.featureStore.accept((Object obj) -> {
114
                selection.add(((Feature) obj).getReference().getCode());
115
            });
116
        } catch (BaseException ex) {
117
            throw new RuntimeException("Can't select all", ex);
118
        }
119
    }
120
121
    @Override
122
    public void deselectAll() throws DataException {
123
        this.selection.clear();
124
    }
125
126
    @Override
127
    public boolean isSelected(FeatureReference reference) {
128
        return this.selection.contains(reference.getCode());
129
    }
130
131
    @Override
132
    public void reverse() {
133
        try {
134
            this.featureStore.accept((Object obj) -> {
135
                String key = ((Feature) obj).getReference().getCode();
136
                if(selection.contains(key)) {
137
                    selection.remove(key);
138
                } else {
139
                    selection.add(key);
140
                }
141
            });
142
        } catch (BaseException ex) {
143
            throw new RuntimeException("Can't reverse selection", ex);
144
        }
145
    }
146
147
    public boolean isEmpty() {
148
        if (this.selection == null) {
149
            return true;
150
        }
151
        return this.getSelectedCount() == 0;
152
    }
153
154
    @Override
155
    public long getSelectedCount() {
156 45469 jjdelcerro
        try {
157
            return ((Size64)selection).size64();
158
        } catch(Exception ex) {
159
            return selection.size();
160
        }
161 45426 fdiaz
    }
162
163
    @Override
164 46309 jjdelcerro
    public Iterator<FeatureReference> referenceIterator() {
165 45426 fdiaz
        Iterator<String> it = selection.iterator();
166
        Iterator<FeatureReference> itFeatureReferences = new Iterator<FeatureReference>() {
167
            @Override
168
            public boolean hasNext() {
169
                return it.hasNext();
170
            }
171
172
            @Override
173
            public FeatureReference next() {
174
                String code = it.next();
175
                FeatureReference fref = featureStore.getFeatureReference(code);
176
                return fref;
177
            }
178
        };
179
        return itFeatureReferences;
180
    }
181
182
    @Override
183 46309 jjdelcerro
    @SuppressWarnings("Convert2Lambda")
184
    public Iterable<FeatureReference> referenceIterable() {
185
        return new Iterable<FeatureReference>() {
186
            @Override
187
            public Iterator<FeatureReference> iterator() {
188
                Iterator<String> it = selection.iterator();
189
190
                return new Iterator<FeatureReference>() {
191
                    @Override
192
                    public boolean hasNext() {
193
                        return it.hasNext();
194
                    }
195
196
                    @Override
197
                    public FeatureReference next() {
198
                        String code = it.next();
199
                        FeatureReference fref = featureStore.getFeatureReference(code);
200
                        return fref;
201
                    }
202
                };
203
            }
204
        };
205
    }
206
207
    @Override
208 45426 fdiaz
    public boolean isAvailable() {
209
        if (this.available == null) {
210
            this.available = false;
211
            if(this.featureStore != null){
212
                try {
213
                    FeatureType type = this.featureStore.getDefaultFeatureType();
214
                    this.available = type.supportReferences();
215
                } catch (DataException ex) {
216
                    this.available = false;
217
                }
218
            }
219
        }
220
        return this.available;
221
    }
222
223
    @Override
224
    public boolean isFromStore(DataStore store) {
225
        return featureStore.equals(store);
226
    }
227
228
    @Override
229
    public void accept(Visitor visitor) throws BaseException {
230
        for (String string : selection) {
231
            FeatureReference fref = featureStore.getFeatureReference(string);
232
            visitor.visit(fref);
233
        }
234
    }
235
236
    @Override
237
    protected void doDispose() throws BaseException {
238
        delegateObservable.deleteObservers();
239
        deselectAll();
240
        DisposeUtils.dispose(this.featureStore);
241
        DisposeUtils.dispose(this.selection);
242
        this.delegateObservable = null;
243
        this.featureStore = null;
244
        this.selection = null;
245
    }
246
247
    @Override
248
    public void addObserver(Observer observer) {
249
        delegateObservable.addObserver(observer);
250
    }
251
252
    @Override
253
    public void beginComplexNotification() {
254
        delegateObservable.beginComplexNotification();
255
    }
256
257
    @Override
258
    public void deleteObserver(Observer observer) {
259
        delegateObservable.deleteObserver(observer);
260
    }
261
262
    @Override
263
    public void deleteObservers() {
264
        delegateObservable.deleteObservers();
265
    }
266
267
    @Override
268
    public void disableNotifications() {
269
        delegateObservable.disableNotifications();
270
    }
271
272
    @Override
273
    public void enableNotifications() {
274
        delegateObservable.enableNotifications();
275
    }
276
277
    @Override
278
    public void endComplexNotification() {
279
        // We don't want to notify many times in a complex notification
280
        // scenario, so ignore notifications if in complex.
281
        // Only one notification will be sent when the complex notification
282
        // ends.
283
        delegateObservable.notifyObservers(DataStoreNotification.SELECTION_CHANGE);
284
        delegateObservable.endComplexNotification();
285
    }
286
287
    public boolean inComplex() {
288
        return delegateObservable.inComplex();
289
    }
290
291
    public boolean isEnabledNotifications() {
292
        return delegateObservable.isEnabledNotifications();
293
    }
294
295
    public void notifyObservers() {
296
        // We don't want to notify many times in a complex notification
297
        // scenario, so ignore notifications if in complex.
298
        // Only one notification will be sent when the complex notification
299
        // ends.
300
        if (!delegateObservable.inComplex()) {
301
            delegateObservable.notifyObservers();
302
        }
303
    }
304
305
    public void notifyObservers(Object arg) {
306
        if (!delegateObservable.inComplex()) {
307
            delegateObservable.notifyObservers(arg);
308
        }
309
    }
310
311
//    @Override
312
//    public Object clone() throws CloneNotSupportedException {
313
//        LargeFeatureReferenceSelection clone = (LargeFeatureReferenceSelection) super.clone();
314
//        // Original observers aren't cloned
315
//        clone.delegateObservable = new DelegateWeakReferencingObservable(clone);
316
//        // Clone internal data
317
//        clone.selection = new LargeMapImpl<>();
318
//        for (Map.Entry<String, Boolean> entry : selection.entrySet()) {
319
//            String key = entry.getKey();
320
//            Boolean val = entry.getValue();
321
//            clone.selection.put(key, val);
322
//        }
323
//        return clone;
324
//    }
325
326
327
    @Override
328
    public void update(Observable observable, Object notification) {
329
        // If a Feature is deleted, remove it from the selection Set.
330
        if (notification instanceof FeatureStoreNotification) {
331
            FeatureStoreNotification storeNotif = (FeatureStoreNotification) notification;
332
            if (FeatureStoreNotification.AFTER_DELETE
333
                    .equalsIgnoreCase(storeNotif.getType())) {
334
                this.deselect(storeNotif.getFeature().getReference());
335
            }
336
        }
337
    }
338
339
    @Override
340
    public void saveToState(PersistentState state) throws PersistenceException {
341
        state.set("store", featureStore);
342
    }
343
344
    @Override
345
    public void loadFromState(PersistentState state) throws PersistenceException {
346 45469 jjdelcerro
        featureStore = (DefaultFeatureStore) state.get("store");
347 45426 fdiaz
        if(selection != null) {
348
            this.selection.clear();
349
        } else {
350 45469 jjdelcerro
            this.selection = this.featureStore.getManager().createLargeSet();
351 45426 fdiaz
        }
352
        Iterator it = state.getIterator("selected");
353
        while (it!=null && it.hasNext()) {
354 45647 fdiaz
            FeatureReference ref = (FeatureReference) it.next();
355 45426 fdiaz
            this.select(ref);
356
        }
357
358
        /*
359
             * If we do not do this, feature store will not listen
360
             * to changes in selection after instantiating a
361
             * persisted selection. For non-persisted instances,
362
             * this line corresponds to the line found in method:
363
             * getFeatureSelection() in DefaultFeatureStore.
364
             * This is not dangerous because "addObserver" only adds
365
             * if they were not already added, so future invocations
366
             * with same instances will have no effect.
367
         */
368
        this.addObserver((DefaultFeatureStore) featureStore);
369
    }
370
371
    protected void clearFeatureReferences() {
372
        if (this.selection == null) {
373
            return;
374
        }
375
        this.selection.clear();
376
    }
377
378
    public List<FeatureType> getFeatureTypes() {
379
        try {
380
            return featureStore.getFeatureTypes();
381
        } catch (Exception e) {
382
            throw new RuntimeException(e);
383
        }
384
    }
385
386
        public static void registerPersistent() {
387
        DynStruct definition = ToolsLocator.getPersistenceManager().addDefinition(
388
                DefaultFeatureReferenceSelection.class,
389
                DYNCLASS_PERSISTENT_NAME,
390
                "LargeFeatureReferenceSelection Persistent definition",
391
                null,
392
                null
393
        );
394
395
        definition.addDynFieldObject("store").setClassOfValue(FeatureStore.class).setMandatory(true);
396
//        definition.addDynFieldLong("totalSize").setMandatory(true);
397 45647 fdiaz
        definition.addDynFieldList("selected").setClassOfItems(FeatureReference.class).setMandatory(false);
398 45426 fdiaz
399
    }
400
401
402
403
}