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 / FeatureManager.java @ 43722

History | View | Annotate | Download (11.6 KB)

1
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright (C) 2007-2013 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, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21
 * For any additional information, do not hesitate to contact us
22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
23
 */
24
package org.gvsig.fmap.dal.feature.impl;
25

    
26
import java.util.Collection;
27
import java.util.HashMap;
28
import java.util.Iterator;
29
import java.util.LinkedHashMap;
30
import java.util.LinkedHashSet;
31
import java.util.Map;
32
import java.util.NoSuchElementException;
33

    
34
import org.gvsig.fmap.dal.exception.DataException;
35
import org.gvsig.fmap.dal.feature.EditableFeature;
36
import org.gvsig.fmap.dal.feature.Feature;
37
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
38
import org.gvsig.fmap.dal.feature.FeatureReference;
39
import org.gvsig.fmap.dal.feature.FeatureStore;
40
import org.gvsig.fmap.dal.feature.FeatureType;
41
import org.gvsig.fmap.dal.feature.impl.expansionadapter.ExpansionAdapter;
42

    
43

    
44
/**
45
 * DOCUMENT ME!
46
 *
47
 * @author Vicente Caballero Navarro
48
 */
49
public class FeatureManager {
50
    private ExpansionAdapter expansionAdapter;
51
    private Collection deleted = new LinkedHashSet();//<FeatureID>
52
    private int deltaSize=0;
53
        private Map added = new LinkedHashMap();
54
        private Map addedAndDeleted = new LinkedHashMap();
55
        private HashMap modifiedFromOriginal=new HashMap();
56

    
57
        public FeatureManager(ExpansionAdapter expansionAdapter){
58
            this.expansionAdapter=expansionAdapter;
59
    }
60

    
61
        /**
62
         * Deletes feature from this manager.
63
         * @param id
64
         * @return The deleted feature or null if the
65
         * feature had not been edited or previously added in the editing session
66
         */
67
    public Feature delete(FeatureReference id) {
68
        deleted.add(id);
69
                Integer num = (Integer) added.remove(id);
70
        Feature feature=null;
71
        if (num == null || num.intValue() == -1) {
72
            num = (Integer) modifiedFromOriginal.remove(id);
73
            if (num != null) {
74
                feature = (Feature) expansionAdapter.getObject(num.intValue());
75
            }
76
            // if num is null here, method returns null
77
                }else{
78
                        feature = (Feature) expansionAdapter.getObject(num.intValue());
79
                        addedAndDeleted.put(id, num);
80
                }
81
        deltaSize--;
82
        return feature;
83
    }
84

    
85
    /**
86
     * DOCUMENT ME!
87
     *
88
     * @param feature DOCUMENT ME!
89
     */
90
    public void add(Feature feature) {
91
        int pos = expansionAdapter.addObject(feature);
92
        added.put(feature.getReference(),new Integer(pos));
93
        deleted.remove(feature.getReference());
94
        deltaSize++;
95
    }
96

    
97
    /**
98
     * DOCUMENT ME!
99
     * @param id DOCUMENT ME!
100
     */
101
    public Feature deleteLastFeature() {
102
        expansionAdapter.deleteLastObject();
103
        Feature feature=(Feature)expansionAdapter.getObject(expansionAdapter.getSize()-1);
104
        added.remove(feature.getReference());
105
        modifiedFromOriginal.remove(feature.getReference());
106
        deltaSize--;
107
        return feature;
108
    }
109

    
110
    /**
111
     * Returns a Feature of the default type.
112
     *
113
     * @param id
114
     *            the feature reference
115
     * @param store
116
     *            the store to get the feature from
117
     * @return a Feature with the given reference
118
     * @throws DataException
119
     *             if there is an error getting the Feature
120
     */
121
    public Feature get(FeatureReference id, FeatureStore store)
122
            throws DataException {
123
        return get(id, store, null);
124
    }
125

    
126
    /**
127
     * Returns a Feature of the given type.
128
     *
129
     * @param id
130
     *            the feature reference
131
     * @param store
132
     *            the store to get the feature from
133
     * @param featureType
134
     *            the type of the feature to return
135
     * @return a Feature with the given reference
136
     * @throws DataException
137
     *             if there is an error getting the Feature
138
     */
139
    public Feature get(FeatureReference id, FeatureStore store,
140
                        FeatureType featureType) throws DataException {
141
            // FIXME: y si el featuretype que paso esta modificado.
142
            //        Deberia buscarlo en el featuretypemanager ?
143
                //
144
            //        Si no existe feature con ese id... ? retorna null ?
145
            //        en EditedDefaultIterator se hace uso de ese comportamiento.
146
            //
147
            Integer intNum = ((Integer) added.get(id));
148
            if (intNum == null){
149
                    intNum =((Integer) modifiedFromOriginal.get(id));
150
                if (intNum == null){
151
                    //If the feature has been added and deleted
152
                    intNum = (Integer)addedAndDeleted.get(id);
153
                    if (intNum == null){
154
                        return null;
155
                    }
156
                }
157
            }
158
        int num = intNum.intValue();
159
        if (num==-1) {
160
                        return null;
161
                }
162
        Feature feature=(Feature)expansionAdapter.getObject(num);
163
        if (featureType== null){
164
                featureType = store.getDefaultFeatureType();
165
        }
166
               return getCorrectFeature(feature, store,featureType);
167
    }
168

    
169
    private Feature getCorrectFeature(
170
            Feature feature, 
171
            FeatureStore store,
172
            FeatureType featureType
173
        ) throws DataException {
174

    
175
        Feature sourceFeature = feature;
176
        FeatureType sourceType = sourceFeature.getType();
177
        
178
        FeatureType targetType = featureType;
179
        EditableFeature targetFeature = store.createNewFeature(featureType, false);
180
        
181
        for (FeatureAttributeDescriptor targetAttrDescriptor : targetType) {
182
            if ( targetAttrDescriptor.isAutomatic() || 
183
                 targetAttrDescriptor.isReadOnly() || 
184
                 targetAttrDescriptor.getEvaluator() != null) {
185
                 continue;
186
            }
187
            int sourceIndex = sourceType.getIndex(targetAttrDescriptor.getName());
188
            if (sourceIndex<0){
189
                continue;
190
            }
191
            Object value = sourceFeature.get(sourceIndex);
192
            if (value == null && !targetAttrDescriptor.allowNull()) {
193
                continue;
194
            }
195
            targetFeature.set(targetAttrDescriptor.getIndex(),value);
196
        }
197
        return targetFeature.getNotEditableCopy();        
198
    }
199

    
200
        /**
201
     * DOCUMENT ME!
202
     *
203
     * @param feature DOCUMENT ME!
204
     * @param oldFeature DOCUMENT ME!
205
     */
206
    public int update(Feature feature, Feature oldFeature) {
207
            int oldNum=-1;
208
        int num = expansionAdapter.addObject(feature);
209
        FeatureReference id=feature.getReference();
210
        if (added.containsKey(id)){
211
                oldNum=((Integer)added.get(id)).intValue();
212
                added.put(id,new Integer(num));
213
        }else{
214
                if (modifiedFromOriginal.get(id)!=null) {
215
                                oldNum=((Integer)modifiedFromOriginal.get(id)).intValue();
216
                        }
217
                modifiedFromOriginal.put(id,new Integer(num));
218
        }
219
        return oldNum;
220
    }
221

    
222
    /**
223
     * DOCUMENT ME!
224
     *
225
     * @param id DOCUMENT ME!
226
     */
227
    public void restore(FeatureReference id) {
228
        deleted.remove(id);
229
        deltaSize++;
230
    }
231
    public void restore(FeatureReference id,int num){
232
            if (added.containsKey(id)){
233
                added.put(id,new Integer(num));
234
        }else{
235
                modifiedFromOriginal.put(id,new Integer(num));
236
        }
237
    }
238

    
239

    
240
    public boolean isDeleted(Feature feature){
241
            return deleted.contains(feature.getReference());
242
    }
243

    
244
    public boolean isDeleted(FeatureReference featureID) {
245
                return deleted.contains(featureID);
246
        }
247

    
248
        public void clear() {
249
                added.clear();
250
                modifiedFromOriginal.clear();
251
            expansionAdapter.close();
252
            deleted.clear();//<FeatureID>
253
            addedAndDeleted.clear();
254
            deltaSize=0;
255
        }
256

    
257

    
258
        public boolean hasChanges() {
259
                return added.size()>0 || modifiedFromOriginal.size() > 0 || deleted.size() > 0;
260
        }
261

    
262
        public Iterator getDeleted() {
263
                return new DeletedIterator();
264

    
265
        }
266

    
267
        class DeletedIterator implements Iterator {
268
                private Boolean hasnext = null;
269
                private Iterator iter;
270
                private DefaultFeatureReference obj;
271

    
272
                public DeletedIterator(){
273
                        iter = deleted.iterator();
274
                }
275

    
276
                public boolean hasNext() {
277
                        if (hasnext != null) {
278
                                return hasnext.booleanValue();
279
                        }
280
                        hasnext = Boolean.FALSE;
281
                        while (iter.hasNext()) {
282
                                obj = (DefaultFeatureReference) iter.next();
283
                                if (obj.isNewFeature()) {
284
                                        continue;
285
                                }
286
                                hasnext = Boolean.TRUE;
287
                                break;
288
                        }
289
                        return hasnext.booleanValue();
290
                }
291

    
292
                public Object next() {
293
                        if (!hasNext()) {
294
                                throw new NoSuchElementException();
295
                        }
296

    
297
                        hasnext = null;
298
                        return obj;
299
                }
300

    
301
                public void remove() {
302
                        throw new UnsupportedOperationException();
303

    
304
                }
305

    
306
        }
307

    
308
        public Iterator getInserted() {
309
                return new InsertedIterator();
310
        }
311

    
312
        class InsertedIterator implements Iterator {
313

    
314
                private Iterator addedIter;
315
                private DefaultFeature obj;
316
                private Boolean hasnext = null;
317

    
318
                public InsertedIterator(){
319
                        addedIter = added.values().iterator();
320
                }
321

    
322
                public boolean hasNext() {
323
                        if (hasnext != null) {
324
                                return hasnext.booleanValue();
325
                        }
326
                        hasnext = Boolean.FALSE;
327
                        int pos;
328
                        while (addedIter.hasNext()) {
329
                                pos = ((Integer) addedIter.next()).intValue();
330
                                obj = (DefaultFeature) expansionAdapter.getObject(pos);
331
                                if (!deleted.contains(obj.getReference())) {
332
                                        hasnext = Boolean.TRUE;
333
                                        break;
334
                                }
335
                        }
336
                        return hasnext.booleanValue();
337
                }
338

    
339
                public Object next() {
340
                        if (!hasNext()) {
341
                                throw new NoSuchElementException();
342
                        }
343
                        hasnext = null;
344
                        return obj.getData();
345
                }
346

    
347
                public void remove() {
348
                        addedIter.remove();
349
                }
350

    
351
        }
352
        public Iterator getUpdated() {
353
                return new UpdatedIterator();
354
        }
355
        class UpdatedIterator implements Iterator{
356
                private Boolean hasnext = null;
357
                private Iterator iter;
358
                private DefaultFeature obj;
359
                private int pos;
360

    
361
                public UpdatedIterator() {
362
                        iter = expansionAdapter.iterator();
363
                        pos = -1;
364
                }
365

    
366
                public boolean hasNext() {
367
                        if (hasnext != null) {
368
                                return hasnext.booleanValue();
369
                        }
370
                        hasnext = Boolean.FALSE;
371
                        while (iter.hasNext()) {
372
                                pos++;
373
                                obj = (DefaultFeature) iter.next();
374
                                if (deleted.contains(obj.getReference())){
375
                                        continue;
376
                                }else if (!modifiedFromOriginal.containsValue(new Integer(pos))){
377
                                        continue;
378
                                }else {
379
                                        hasnext = Boolean.TRUE;
380
                                        break;
381
                                }
382
                        }
383
                        return hasnext.booleanValue();
384
                }
385

    
386
                public Object next() {
387
                        if (!hasNext()) {
388
                                throw new NoSuchElementException();
389
                        }
390
                        hasnext = null;
391
                        return obj.getData();
392
                }
393

    
394
                public void remove() {
395
                        throw new UnsupportedOperationException();
396

    
397
                }
398
        }
399

    
400
        public boolean hasNews() {
401
                return !added.isEmpty();
402
        }
403

    
404
        public long getDeltaSize() {
405
                return deltaSize;
406
        }
407

    
408
    /**
409
     * Indicates if any operation has comprimised the selected features.
410
     * @return
411
     */
412
    public boolean isSelectionCompromised() {
413
        //Only deleted features can change order, as added features are added at the end.
414
        return deleted.size()>0;
415
    }
416
}