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

History | View | Annotate | Download (12.4 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
    public Iterator referenceIterator() {
165
166
        Iterator<String> it = selection.iterator();
167
168
        Iterator<FeatureReference> itFeatureReferences = new Iterator<FeatureReference>() {
169
            @Override
170
            public boolean hasNext() {
171
                return it.hasNext();
172
            }
173
174
            @Override
175
            public FeatureReference next() {
176
                String code = it.next();
177
                FeatureReference fref = featureStore.getFeatureReference(code);
178
                return fref;
179
            }
180
        };
181
        return itFeatureReferences;
182
    }
183
184
    @Override
185
    public boolean isAvailable() {
186
        if (this.available == null) {
187
            this.available = false;
188
            if(this.featureStore != null){
189
                try {
190
                    FeatureType type = this.featureStore.getDefaultFeatureType();
191
                    this.available = type.supportReferences();
192
                } catch (DataException ex) {
193
                    this.available = false;
194
                }
195
            }
196
        }
197
        return this.available;
198
    }
199
200
    @Override
201
    public boolean isFromStore(DataStore store) {
202
        return featureStore.equals(store);
203
    }
204
205
    @Override
206
    public void accept(Visitor visitor) throws BaseException {
207
        for (String string : selection) {
208
            FeatureReference fref = featureStore.getFeatureReference(string);
209
            visitor.visit(fref);
210
        }
211
    }
212
213
    @Override
214
    protected void doDispose() throws BaseException {
215
        delegateObservable.deleteObservers();
216
        deselectAll();
217
        DisposeUtils.dispose(this.featureStore);
218
        DisposeUtils.dispose(this.selection);
219
        this.delegateObservable = null;
220
        this.featureStore = null;
221
        this.selection = null;
222
    }
223
224
    @Override
225
    public void addObserver(Observer observer) {
226
        delegateObservable.addObserver(observer);
227
    }
228
229
    @Override
230
    public void beginComplexNotification() {
231
        delegateObservable.beginComplexNotification();
232
    }
233
234
    @Override
235
    public void deleteObserver(Observer observer) {
236
        delegateObservable.deleteObserver(observer);
237
    }
238
239
    @Override
240
    public void deleteObservers() {
241
        delegateObservable.deleteObservers();
242
    }
243
244
    @Override
245
    public void disableNotifications() {
246
        delegateObservable.disableNotifications();
247
    }
248
249
    @Override
250
    public void enableNotifications() {
251
        delegateObservable.enableNotifications();
252
    }
253
254
    @Override
255
    public void endComplexNotification() {
256
        // We don't want to notify many times in a complex notification
257
        // scenario, so ignore notifications if in complex.
258
        // Only one notification will be sent when the complex notification
259
        // ends.
260
        delegateObservable.notifyObservers(DataStoreNotification.SELECTION_CHANGE);
261
        delegateObservable.endComplexNotification();
262
    }
263
264
    public boolean inComplex() {
265
        return delegateObservable.inComplex();
266
    }
267
268
    public boolean isEnabledNotifications() {
269
        return delegateObservable.isEnabledNotifications();
270
    }
271
272
    public void notifyObservers() {
273
        // We don't want to notify many times in a complex notification
274
        // scenario, so ignore notifications if in complex.
275
        // Only one notification will be sent when the complex notification
276
        // ends.
277
        if (!delegateObservable.inComplex()) {
278
            delegateObservable.notifyObservers();
279
        }
280
    }
281
282
    public void notifyObservers(Object arg) {
283
        if (!delegateObservable.inComplex()) {
284
            delegateObservable.notifyObservers(arg);
285
        }
286
    }
287
288
//    @Override
289
//    public Object clone() throws CloneNotSupportedException {
290
//        LargeFeatureReferenceSelection clone = (LargeFeatureReferenceSelection) super.clone();
291
//        // Original observers aren't cloned
292
//        clone.delegateObservable = new DelegateWeakReferencingObservable(clone);
293
//        // Clone internal data
294
//        clone.selection = new LargeMapImpl<>();
295
//        for (Map.Entry<String, Boolean> entry : selection.entrySet()) {
296
//            String key = entry.getKey();
297
//            Boolean val = entry.getValue();
298
//            clone.selection.put(key, val);
299
//        }
300
//        return clone;
301
//    }
302
303
304
    @Override
305
    public void update(Observable observable, Object notification) {
306
        // If a Feature is deleted, remove it from the selection Set.
307
        if (notification instanceof FeatureStoreNotification) {
308
            FeatureStoreNotification storeNotif = (FeatureStoreNotification) notification;
309
            if (FeatureStoreNotification.AFTER_DELETE
310
                    .equalsIgnoreCase(storeNotif.getType())) {
311
                this.deselect(storeNotif.getFeature().getReference());
312
            }
313
        }
314
    }
315
316
    @Override
317
    public void saveToState(PersistentState state) throws PersistenceException {
318
        state.set("store", featureStore);
319
    }
320
321
    @Override
322
    public void loadFromState(PersistentState state) throws PersistenceException {
323 45469 jjdelcerro
        featureStore = (DefaultFeatureStore) state.get("store");
324 45426 fdiaz
        if(selection != null) {
325
            this.selection.clear();
326
        } else {
327 45469 jjdelcerro
            this.selection = this.featureStore.getManager().createLargeSet();
328 45426 fdiaz
        }
329
        Iterator it = state.getIterator("selected");
330
        while (it!=null && it.hasNext()) {
331 45647 fdiaz
            FeatureReference ref = (FeatureReference) it.next();
332 45426 fdiaz
            this.select(ref);
333
        }
334
335
        /*
336
             * If we do not do this, feature store will not listen
337
             * to changes in selection after instantiating a
338
             * persisted selection. For non-persisted instances,
339
             * this line corresponds to the line found in method:
340
             * getFeatureSelection() in DefaultFeatureStore.
341
             * This is not dangerous because "addObserver" only adds
342
             * if they were not already added, so future invocations
343
             * with same instances will have no effect.
344
         */
345
        this.addObserver((DefaultFeatureStore) featureStore);
346
    }
347
348
    protected void clearFeatureReferences() {
349
        if (this.selection == null) {
350
            return;
351
        }
352
        this.selection.clear();
353
    }
354
355
    public List<FeatureType> getFeatureTypes() {
356
        try {
357
            return featureStore.getFeatureTypes();
358
        } catch (Exception e) {
359
            throw new RuntimeException(e);
360
        }
361
    }
362
363
        public static void registerPersistent() {
364
        DynStruct definition = ToolsLocator.getPersistenceManager().addDefinition(
365
                DefaultFeatureReferenceSelection.class,
366
                DYNCLASS_PERSISTENT_NAME,
367
                "LargeFeatureReferenceSelection Persistent definition",
368
                null,
369
                null
370
        );
371
372
        definition.addDynFieldObject("store").setClassOfValue(FeatureStore.class).setMandatory(true);
373
//        definition.addDynFieldLong("totalSize").setMandatory(true);
374 45647 fdiaz
        definition.addDynFieldList("selected").setClassOfItems(FeatureReference.class).setMandatory(false);
375 45426 fdiaz
376
    }
377
378
379
380
}