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 / editing / memory / FeatureTypeManager.java @ 43981

History | View | Annotate | Download (15.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 41926 jjdelcerro
 * This program is free software; you can redistribute it and/or modify it under
7
 * the terms of the GNU General Public License as published by the Free Software
8
 * Foundation; either version 3 of the License, or (at your option) any later
9
 * version.
10 40435 jjdelcerro
 *
11 41926 jjdelcerro
 * This program is distributed in the hope that it will be useful, but WITHOUT
12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
14
 * details.
15 40435 jjdelcerro
 *
16 41926 jjdelcerro
 * You should have received a copy of the GNU General Public License along with
17
 * this program; if not, write to the Free Software Foundation, Inc., 51
18
 * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 40435 jjdelcerro
 *
20 41926 jjdelcerro
 * For any additional information, do not hesitate to contact us at info AT
21
 * gvsig.com, or visit our website www.gvsig.com.
22 40435 jjdelcerro
 */
23 43840 jjdelcerro
package org.gvsig.fmap.dal.feature.impl.editing.memory;
24 40435 jjdelcerro
25
import java.lang.ref.WeakReference;
26
import java.util.ArrayList;
27
import java.util.Arrays;
28
import java.util.HashMap;
29
import java.util.Iterator;
30
import java.util.List;
31 43840 jjdelcerro
import java.util.Map;
32 40435 jjdelcerro
33
import org.gvsig.fmap.dal.exception.DataException;
34
import org.gvsig.fmap.dal.feature.AbstractFeatureStoreTransform;
35
import org.gvsig.fmap.dal.feature.EditableFeature;
36
import org.gvsig.fmap.dal.feature.EditableFeatureAttributeDescriptor;
37
import org.gvsig.fmap.dal.feature.EditableFeatureType;
38
import org.gvsig.fmap.dal.feature.Feature;
39
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
40
import org.gvsig.fmap.dal.feature.FeatureStore;
41
import org.gvsig.fmap.dal.feature.FeatureStoreTransform;
42
import org.gvsig.fmap.dal.feature.FeatureType;
43 43840 jjdelcerro
import org.gvsig.fmap.dal.feature.impl.DefaultFeatureStoreTransforms;
44 40435 jjdelcerro
import org.gvsig.fmap.dal.feature.spi.FeatureStoreProvider.FeatureTypeChanged;
45
import org.gvsig.tools.persistence.PersistentState;
46
import org.gvsig.tools.persistence.exception.PersistenceException;
47
48
public class FeatureTypeManager {
49
50 43840 jjdelcerro
    private final ExpansionAdapter expansionAdapter;
51
    private final Map<String,Integer> added = new HashMap();
52
    private final Map<String,Integer> modifiedFromOriginal = new HashMap();
53
    private final List<String> deleted = new ArrayList();
54
55
    private final FeatureTypeManagerFeatureStoreTransforms transforms;
56
    private final FeatureStore store;
57
58 41926 jjdelcerro
    private int deltaSize = 0;
59 43840 jjdelcerro
    private boolean first = true;
60 41926 jjdelcerro
    private FeatureType originalType = null;
61 40435 jjdelcerro
62 43840 jjdelcerro
    public FeatureTypeManager(FeatureStore store) {
63
        this.expansionAdapter = new MemoryExpansionAdapter();
64 41926 jjdelcerro
        this.store = store;
65
        this.transforms = new FeatureTypeManagerFeatureStoreTransforms();
66
        this.transforms.setFeatureStore(store);
67
    }
68 40435 jjdelcerro
69 41926 jjdelcerro
    public void dispose() {
70
        this.expansionAdapter.close();
71
        this.deleted.clear();
72
        this.transforms.clear();
73 43840 jjdelcerro
        this.added.clear();
74
        this.modifiedFromOriginal.clear();
75 41926 jjdelcerro
    }
76 40435 jjdelcerro
77 41926 jjdelcerro
    public FeatureType getType(String id) throws DataException {
78 43840 jjdelcerro
        Integer num = added.get(id);
79
        if (num == null) {
80
            num = modifiedFromOriginal.get(id);
81
            if (num == null) {
82 41926 jjdelcerro
                return null;
83
            }
84
        }
85
        if (num == -1) {
86
            /*
87
             * This happens for example when we are going back to the
88
             * original feature type which is not managed by
89
             * expansionAdapter
90
             */
91
            return null;
92
        }
93
        FeatureType type = (FeatureType) expansionAdapter.getObject(num);
94
        return type;
95
    }
96 40435 jjdelcerro
97 41926 jjdelcerro
    public int update(FeatureType type, FeatureType oldType) {
98
        // deleted.add(oldType.getId());
99
        if (first) {
100
            originalType = oldType;
101
            first = false;
102
        }
103
        int oldNum = -1;
104
        int num = expansionAdapter.addObject(type);
105
        String id = type.getId();
106 40435 jjdelcerro
107 41926 jjdelcerro
        if (added.containsKey(id)) {
108 43840 jjdelcerro
            oldNum = added.get(id);
109
            added.put(id, num);
110 41926 jjdelcerro
        } else {
111
            if (modifiedFromOriginal.get(id) != null) {
112 43840 jjdelcerro
                oldNum = modifiedFromOriginal.get(id);
113 41926 jjdelcerro
            }
114 43840 jjdelcerro
            modifiedFromOriginal.put(id, num);
115 41926 jjdelcerro
        }
116
117
        try {
118
            this.transforms.add(new UpdateFeatureTypeTransform(this.store,
119
                    oldType, type));
120
        } catch (DataException e) {
121
            throw new RuntimeException(); // FIXME (pero esto no deberia de
122
            // pasar nunca)
123
        }
124
        return oldNum;
125
    }
126
127
    private class UpdateFeatureTypeTransform extends AbstractFeatureStoreTransform {
128
129 43840 jjdelcerro
        private final FeatureType ftSource;
130 41926 jjdelcerro
131 40435 jjdelcerro
        private EditableFeatureType ftTarget_editable;
132 43840 jjdelcerro
        private final FeatureType ftTarget_non_editable;
133 40435 jjdelcerro
134 41926 jjdelcerro
        private WeakReference wkRefStore;
135
        private List ftypes = null;
136
        private List attrInSourceToUse;
137 40435 jjdelcerro
138 41926 jjdelcerro
        UpdateFeatureTypeTransform(FeatureStore featureStore,
139
                FeatureType ftSource, FeatureType ftTarget) {
140
            this.ftSource = ftSource;
141 40435 jjdelcerro
142 41926 jjdelcerro
            if (ftTarget instanceof EditableFeatureType) {
143 40435 jjdelcerro
144 41926 jjdelcerro
                ftTarget_editable = (EditableFeatureType) ftTarget;
145
                ftTarget_non_editable = ftTarget_editable.getNotEditableCopy();
146
            } else {
147
                ftTarget_non_editable = ftTarget;
148
            }
149 40435 jjdelcerro
150 41926 jjdelcerro
            this.wkRefStore = new WeakReference(featureStore);
151
            this.initializeAttributesToUse();
152
        }
153
154
        private void initializeAttributesToUse() {
155
            attrInSourceToUse = new ArrayList();
156
157 43840 jjdelcerro
            Iterator iter;
158 41926 jjdelcerro
            if (ftTarget_editable != null) {
159
                iter = ftTarget_editable.iterator();
160
            } else {
161
                iter = ftTarget_non_editable.iterator();
162
            }
163
164
            FeatureAttributeDescriptor tAttr, sAttr;
165 43840 jjdelcerro
            EditableFeatureAttributeDescriptor ead;
166 41926 jjdelcerro
            while (iter.hasNext()) {
167
                tAttr = (FeatureAttributeDescriptor) iter.next();
168
                sAttr = this.ftSource.getAttributeDescriptor(tAttr.getName());
169
                if (sAttr == null) {
170
                    if (tAttr instanceof EditableFeatureAttributeDescriptor) {
171
                        ead = (EditableFeatureAttributeDescriptor) tAttr;
172
                        if (ead.getOriginalName() != null) {
173
                            sAttr = this.ftSource.getAttributeDescriptor(ead.getOriginalName());
174
                            if (sAttr == null) {
175
                                continue;
176
                            }
177
                        } else {
178
                            continue;
179
                        }
180
                    } else {
181
                        continue;
182
                    }
183
                }
184
                if (tAttr.getType() != sAttr.getType()) {
185
                    /*
186
                     * Ignore if type is not the same (user removed field
187
                     * and added another with same name but different type)
188
                     */
189
                    continue;
190
                }
191
                attrInSourceToUse.add(sAttr.getName());
192
            }
193
        }
194
195 43215 jjdelcerro
        @Override
196
        public void setUp() throws Exception {
197
198
        }
199
200 43840 jjdelcerro
        @Override
201 41926 jjdelcerro
        public void applyTransform(Feature source, EditableFeature target)
202
                throws DataException {
203
204
            Iterator iter = target.getType().iterator();
205
            FeatureAttributeDescriptor tAttr;
206
            FeatureAttributeDescriptor tAttr_edi;
207
            FeatureAttributeDescriptor srcAtt;
208
209
            /*
210
             * field name in source feature
211
             */
212 40435 jjdelcerro
            String s_name;
213 41926 jjdelcerro
214 40435 jjdelcerro
            /*
215
             * field name in target feature (the same as in source
216
             * except if renamed)
217
             */
218
            String t_name;
219
220 43840 jjdelcerro
            EditableFeatureAttributeDescriptor eatd;
221 41926 jjdelcerro
            while (iter.hasNext()) {
222
                tAttr = (FeatureAttributeDescriptor) iter.next();
223 43981 omartinez
                if (tAttr.isComputed()) {
224 43978 omartinez
                    continue;
225
                }
226 41926 jjdelcerro
                if (ftTarget_editable != null) {
227
                    /*
228
                     * If target FT is editable, try to get original name
229
                     */
230
                    t_name = tAttr.getName();
231
                    s_name = t_name;
232
                    tAttr_edi = ftTarget_editable.getAttributeDescriptor(t_name);
233
                    if (tAttr_edi instanceof EditableFeatureAttributeDescriptor) {
234
                        eatd = (EditableFeatureAttributeDescriptor) tAttr_edi;
235
                        s_name = eatd.getOriginalName();
236
                    }
237 40435 jjdelcerro
238 41926 jjdelcerro
                    /*
239
                     * If not found, use normal name
240
                     */
241
                    if (s_name == null) {
242
                        s_name = tAttr.getName();
243
                    }
244
                } else {
245
                    /*
246
                     * If target FT is not editable, use normal name
247
                     */
248
                    t_name = tAttr.getName();
249
                    s_name = t_name;
250
                }
251 40435 jjdelcerro
252 41926 jjdelcerro
                srcAtt = source.getType().getAttributeDescriptor(s_name);
253 40435 jjdelcerro
254 41926 jjdelcerro
                if (srcAtt != null
255
                        && /*
256
                         * This prevents the case when user has removed field and
257
                         * added new field with same name and different type.
258
                         * In that case, value will be the default value (else below)
259
                         */ srcAtt.getType() == tAttr.getType()) {
260 40435 jjdelcerro
261 41926 jjdelcerro
                    target.set(t_name, source.get(s_name));
262 40435 jjdelcerro
263 41926 jjdelcerro
                } else {
264
                    target.set(t_name, tAttr.getDefaultValue());
265
                }
266
            }
267
        }
268 40435 jjdelcerro
269 43840 jjdelcerro
        @Override
270 41926 jjdelcerro
        public FeatureType getDefaultFeatureType() throws DataException {
271
            return this.ftTarget_non_editable;
272
        }
273 40435 jjdelcerro
274 43840 jjdelcerro
        @Override
275 41926 jjdelcerro
        public FeatureStore getFeatureStore() {
276
            return (FeatureStore) this.wkRefStore.get();
277
        }
278 40435 jjdelcerro
279 43840 jjdelcerro
        @Override
280 41926 jjdelcerro
        public List getFeatureTypes() throws DataException {
281
            if (this.ftypes == null) {
282
                this.ftypes = Arrays
283
                        .asList(new FeatureType[]{this.ftTarget_non_editable});
284
            }
285
            return this.ftypes;
286
        }
287 40435 jjdelcerro
288 43840 jjdelcerro
        @Override
289 41926 jjdelcerro
        public FeatureType getSourceFeatureTypeFrom(
290
                FeatureType targetFeatureType) {
291
            EditableFeatureType orgType = ftSource.getEditable();
292
            Iterator iter = orgType.iterator();
293
            FeatureAttributeDescriptor attr;
294 43840 jjdelcerro
            EditableFeatureAttributeDescriptor efad;
295 40435 jjdelcerro
296 41926 jjdelcerro
            while (iter.hasNext()) {
297
                attr = (FeatureAttributeDescriptor) iter.next();
298
                if (!attrInSourceToUse.contains(attr.getName())) {
299
                    if (attr instanceof EditableFeatureAttributeDescriptor) {
300
                        efad = (EditableFeatureAttributeDescriptor) attr;
301
                        if (efad.getOriginalName() != null
302
                                && !attrInSourceToUse.contains(efad.getOriginalName())) {
303
                            iter.remove();
304
                        }
305
                    } else {
306
                        iter.remove();
307
                    }
308
                }
309
            }
310
            return orgType.getNotEditableCopy();
311
        }
312 40435 jjdelcerro
313 43840 jjdelcerro
        @Override
314 41926 jjdelcerro
        public void setFeatureStore(FeatureStore featureStore) {
315
            this.wkRefStore = new WeakReference(featureStore);
316
        }
317 40435 jjdelcerro
318 43840 jjdelcerro
        @Override
319 41926 jjdelcerro
        public boolean isTransformsOriginalValues() {
320
            return false;
321
        }
322 40435 jjdelcerro
323 41926 jjdelcerro
    }
324 40435 jjdelcerro
325 41926 jjdelcerro
    public void restore(String id) {
326
        deleted.remove(id);
327
        deltaSize++;
328
    }
329 40435 jjdelcerro
330 41926 jjdelcerro
    public void restore(String id, int num) {
331
        if (added.containsKey(id)) {
332 43840 jjdelcerro
            added.put(id, num);
333 41926 jjdelcerro
        } else {
334 43840 jjdelcerro
            modifiedFromOriginal.put(id, num);
335 41926 jjdelcerro
        }
336
    }
337 40435 jjdelcerro
338 41926 jjdelcerro
    public boolean isDeleted(FeatureType type) {
339
        return deleted.contains(type.getId());
340
    }
341 40435 jjdelcerro
342 41926 jjdelcerro
    public boolean isDeleted(String id) {
343
        return deleted.contains(id);
344
    }
345 40435 jjdelcerro
346 41926 jjdelcerro
    public void clear() {
347
        added.clear();
348
        modifiedFromOriginal.clear();
349
        expansionAdapter.close();
350 43840 jjdelcerro
        deleted.clear();
351 41926 jjdelcerro
        deltaSize = 0;
352
    }
353 40435 jjdelcerro
354 41926 jjdelcerro
    public boolean hasChanges() {
355
        return added.size() > 0 || modifiedFromOriginal.size() > 0
356
                || deleted.size() > 0;
357
    }
358 40435 jjdelcerro
359 41926 jjdelcerro
    public Iterator newsIterator() {
360
        return added.values().iterator();
361
    }
362 40435 jjdelcerro
363 41926 jjdelcerro
    public boolean hasNews() {
364
        return !added.isEmpty();
365
    }
366 40435 jjdelcerro
367 41926 jjdelcerro
    public long getDeltaSize() {
368
        return deltaSize;
369
    }
370 40435 jjdelcerro
371 41926 jjdelcerro
    public FeatureType getOriginalFeatureType() {
372
        return originalType;
373
    }
374 40435 jjdelcerro
375 41926 jjdelcerro
    public DefaultFeatureStoreTransforms getTransforms() {
376
        return this.transforms;
377
    }
378 40435 jjdelcerro
379 41926 jjdelcerro
    public class FeatureTypeManagerFeatureStoreTransforms extends
380
            DefaultFeatureStoreTransforms {
381 40435 jjdelcerro
382 41926 jjdelcerro
        private FeatureTypeManagerFeatureStoreTransforms() {
383 40435 jjdelcerro
384 41926 jjdelcerro
        }
385 40435 jjdelcerro
386 43840 jjdelcerro
        @Override
387 41926 jjdelcerro
        protected void checkEditingMode() {
388
        }
389 40435 jjdelcerro
390 43840 jjdelcerro
        @Override
391 41926 jjdelcerro
        protected void notifyChangeToStore() {
392
        }
393 40435 jjdelcerro
394 41926 jjdelcerro
        public PersistentState getState() throws PersistenceException {
395
            // FIXME
396
            throw new UnsupportedOperationException();
397
        }
398 40435 jjdelcerro
399 41926 jjdelcerro
        public void loadState(PersistentState state)
400
                throws PersistenceException {
401
            // FIXME
402
            throw new UnsupportedOperationException();
403
        }
404 40435 jjdelcerro
405 43840 jjdelcerro
        @Override
406 41926 jjdelcerro
        public void loadFromState(PersistentState state) throws PersistenceException {
407
            // FIXME
408
            throw new UnsupportedOperationException();
409
        }
410 40435 jjdelcerro
411 43840 jjdelcerro
        @Override
412 41926 jjdelcerro
        public FeatureStoreTransform add(FeatureStoreTransform transform)
413
                throws DataException {
414
            if (!(transform instanceof UpdateFeatureTypeTransform)) {
415
                // FIXME
416
                throw new IllegalArgumentException();
417
            }
418
            return super.add(transform);
419
        }
420 40435 jjdelcerro
421 41926 jjdelcerro
    }
422 40435 jjdelcerro
423 41926 jjdelcerro
    public class FeatureTypesChangedItem implements FeatureTypeChanged {
424
425 43840 jjdelcerro
        private final FeatureType source;
426
        private final FeatureType target;
427 41926 jjdelcerro
428
        public FeatureTypesChangedItem(FeatureType source, FeatureType target) {
429
            this.source = source;
430
            this.target = target;
431
        }
432
433 43840 jjdelcerro
        @Override
434 41926 jjdelcerro
        public FeatureType getSource() {
435
            return source;
436
        }
437
438 43840 jjdelcerro
        @Override
439 41926 jjdelcerro
        public FeatureType getTarget() {
440
            return target;
441
        }
442
443
    }
444
445 43967 jjdelcerro
    public List<FeatureTypeChanged> getFeatureTypesChanged() throws DataException {
446 41926 jjdelcerro
        // FIXME this don't work for Store.fType.size() > 1
447
        List list = new ArrayList();
448
        if (modifiedFromOriginal.size() > 0) {
449
            FeatureType src = this.getOriginalFeatureType();
450 43967 jjdelcerro
            list.add(
451
                    new FeatureTypesChangedItem(
452
                            src,
453
                            this.store.getFeatureType(src.getId())
454
                    )
455
            );
456 41926 jjdelcerro
        }
457 43967 jjdelcerro
        return list;
458 41926 jjdelcerro
    }
459
460 40435 jjdelcerro
}