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 / FeatureTypeManager.java @ 42563

History | View | Annotate | Download (14.9 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
package org.gvsig.fmap.dal.feature.impl;
24
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
32
import org.gvsig.fmap.dal.exception.DataException;
33
import org.gvsig.fmap.dal.feature.AbstractFeatureStoreTransform;
34
import org.gvsig.fmap.dal.feature.EditableFeature;
35
import org.gvsig.fmap.dal.feature.EditableFeatureAttributeDescriptor;
36
import org.gvsig.fmap.dal.feature.EditableFeatureType;
37
import org.gvsig.fmap.dal.feature.Feature;
38
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
39
import org.gvsig.fmap.dal.feature.FeatureStore;
40
import org.gvsig.fmap.dal.feature.FeatureStoreTransform;
41
import org.gvsig.fmap.dal.feature.FeatureType;
42
import org.gvsig.fmap.dal.feature.impl.expansionadapter.ExpansionAdapter;
43
import org.gvsig.fmap.dal.feature.spi.FeatureStoreProvider.FeatureTypeChanged;
44
import org.gvsig.tools.persistence.PersistentState;
45
import org.gvsig.tools.persistence.exception.PersistenceException;
46
47
public class FeatureTypeManager {
48
49 41926 jjdelcerro
    private ExpansionAdapter expansionAdapter;
50
    private ArrayList deleted = new ArrayList();// <FeatureID>
51
    private int deltaSize = 0;
52
    private HashMap added = new HashMap();
53
    private HashMap modifiedFromOriginal = new HashMap();
54
    private FeatureType originalType = null;
55
    private boolean first = true;
56
    private FeatureTypeManagerFeatureStoreTransforms transforms;
57
    private FeatureStore store;
58 40435 jjdelcerro
59 41926 jjdelcerro
    public FeatureTypeManager(FeatureStore store,
60
            ExpansionAdapter expansionAdapter) {
61
        this.expansionAdapter = expansionAdapter;
62
        this.store = store;
63
        this.transforms = new FeatureTypeManagerFeatureStoreTransforms();
64
        this.transforms.setFeatureStore(store);
65
    }
66 40435 jjdelcerro
67 41926 jjdelcerro
    public void dispose() {
68
        this.expansionAdapter.close();
69
        this.expansionAdapter = null;
70
        this.deleted.clear();
71
        this.deleted = null;
72
        this.transforms.clear();
73
    }
74 40435 jjdelcerro
75 41926 jjdelcerro
    public FeatureType getType(String id) throws DataException {
76
        Integer intNum = ((Integer) added.get(id));
77
        if (intNum == null) {
78
            intNum = ((Integer) modifiedFromOriginal.get(id));
79
            if (intNum == null) {
80
                return null;
81
            }
82
        }
83
        int num = intNum.intValue();
84 40435 jjdelcerro
85 41926 jjdelcerro
        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 40435 jjdelcerro
94 41926 jjdelcerro
        FeatureType type = (FeatureType) expansionAdapter.getObject(num);
95
        return type;
96
    }
97 40435 jjdelcerro
98 41926 jjdelcerro
    public int update(FeatureType type, FeatureType oldType) {
99
        // deleted.add(oldType.getId());
100
        if (first) {
101
            originalType = oldType;
102
            first = false;
103
        }
104
        int oldNum = -1;
105
        int num = expansionAdapter.addObject(type);
106
        String id = type.getId();
107 40435 jjdelcerro
108 41926 jjdelcerro
        if (added.containsKey(id)) {
109
            oldNum = ((Integer) added.get(id)).intValue();
110
            added.put(id, new Integer(num));
111
        } else {
112
            if (modifiedFromOriginal.get(id) != null) {
113
                oldNum = ((Integer) modifiedFromOriginal.get(id)).intValue();
114
            }
115
            modifiedFromOriginal.put(id, new Integer(num));
116
        }
117
118
        try {
119
            this.transforms.add(new UpdateFeatureTypeTransform(this.store,
120
                    oldType, type));
121
        } catch (DataException e) {
122
            throw new RuntimeException(); // FIXME (pero esto no deberia de
123
            // pasar nunca)
124
        }
125
        return oldNum;
126
    }
127
128
    private class UpdateFeatureTypeTransform extends AbstractFeatureStoreTransform {
129
130
        private FeatureType ftSource;
131
132 40435 jjdelcerro
        private EditableFeatureType ftTarget_editable;
133
        private FeatureType ftTarget_non_editable;
134
135 41926 jjdelcerro
        private WeakReference wkRefStore;
136
        private List ftypes = null;
137
        private List attrInSourceToUse;
138 40435 jjdelcerro
139 41926 jjdelcerro
        UpdateFeatureTypeTransform(FeatureStore featureStore,
140
                FeatureType ftSource, FeatureType ftTarget) {
141
            this.ftSource = ftSource;
142 40435 jjdelcerro
143 41926 jjdelcerro
            if (ftTarget instanceof EditableFeatureType) {
144 40435 jjdelcerro
145 41926 jjdelcerro
                ftTarget_editable = (EditableFeatureType) ftTarget;
146
                ftTarget_non_editable = ftTarget_editable.getNotEditableCopy();
147
            } else {
148
                ftTarget_non_editable = ftTarget;
149
            }
150 40435 jjdelcerro
151 41926 jjdelcerro
            this.wkRefStore = new WeakReference(featureStore);
152
            this.initializeAttributesToUse();
153
        }
154
155
        private void initializeAttributesToUse() {
156
            attrInSourceToUse = new ArrayList();
157
158
            Iterator iter = null;
159
            if (ftTarget_editable != null) {
160
                iter = ftTarget_editable.iterator();
161
            } else {
162
                iter = ftTarget_non_editable.iterator();
163
            }
164
165
            FeatureAttributeDescriptor tAttr, sAttr;
166
            EditableFeatureAttributeDescriptor ead = null;
167
            while (iter.hasNext()) {
168
                tAttr = (FeatureAttributeDescriptor) iter.next();
169
                sAttr = this.ftSource.getAttributeDescriptor(tAttr.getName());
170
                if (sAttr == null) {
171
                    if (tAttr instanceof EditableFeatureAttributeDescriptor) {
172
                        ead = (EditableFeatureAttributeDescriptor) tAttr;
173
                        if (ead.getOriginalName() != null) {
174
                            sAttr = this.ftSource.getAttributeDescriptor(ead.getOriginalName());
175
                            if (sAttr == null) {
176
                                continue;
177
                            }
178
                        } else {
179
                            continue;
180
                        }
181
                    } else {
182
                        continue;
183
                    }
184
                }
185
                if (tAttr.getType() != sAttr.getType()) {
186
                    /*
187
                     * Ignore if type is not the same (user removed field
188
                     * and added another with same name but different type)
189
                     */
190
                    continue;
191
                }
192
                attrInSourceToUse.add(sAttr.getName());
193
            }
194
        }
195
196
        public void applyTransform(Feature source, EditableFeature target)
197
                throws DataException {
198
199
            Iterator iter = target.getType().iterator();
200
            FeatureAttributeDescriptor tAttr;
201
            FeatureAttributeDescriptor tAttr_edi;
202
            FeatureAttributeDescriptor srcAtt;
203
204
            /*
205
             * field name in source feature
206
             */
207 40435 jjdelcerro
            String s_name;
208 41926 jjdelcerro
209 40435 jjdelcerro
            /*
210
             * field name in target feature (the same as in source
211
             * except if renamed)
212
             */
213
            String t_name;
214
215 41926 jjdelcerro
            EditableFeatureAttributeDescriptor eatd = null;
216
            while (iter.hasNext()) {
217
                tAttr = (FeatureAttributeDescriptor) iter.next();
218 40435 jjdelcerro
219 41926 jjdelcerro
                if (ftTarget_editable != null) {
220
                    /*
221
                     * If target FT is editable, try to get original name
222
                     */
223
                    t_name = tAttr.getName();
224
                    s_name = t_name;
225
                    tAttr_edi = ftTarget_editable.getAttributeDescriptor(t_name);
226
                    if (tAttr_edi instanceof EditableFeatureAttributeDescriptor) {
227
                        eatd = (EditableFeatureAttributeDescriptor) tAttr_edi;
228
                        s_name = eatd.getOriginalName();
229
                    }
230 40435 jjdelcerro
231 41926 jjdelcerro
                    /*
232
                     * If not found, use normal name
233
                     */
234
                    if (s_name == null) {
235
                        s_name = tAttr.getName();
236
                    }
237
                } else {
238
                    /*
239
                     * If target FT is not editable, use normal name
240
                     */
241
                    t_name = tAttr.getName();
242
                    s_name = t_name;
243
                }
244 40435 jjdelcerro
245 41926 jjdelcerro
                srcAtt = source.getType().getAttributeDescriptor(s_name);
246 40435 jjdelcerro
247 41926 jjdelcerro
                if (srcAtt != null
248
                        && /*
249
                         * This prevents the case when user has removed field and
250
                         * added new field with same name and different type.
251
                         * In that case, value will be the default value (else below)
252
                         */ srcAtt.getType() == tAttr.getType()) {
253 40435 jjdelcerro
254 41926 jjdelcerro
                    target.set(t_name, source.get(s_name));
255 40435 jjdelcerro
256 41926 jjdelcerro
                } else {
257
                    target.set(t_name, tAttr.getDefaultValue());
258
                }
259
            }
260
        }
261 40435 jjdelcerro
262 41926 jjdelcerro
        public FeatureType getDefaultFeatureType() throws DataException {
263
            return this.ftTarget_non_editable;
264
        }
265 40435 jjdelcerro
266 41926 jjdelcerro
        public FeatureStore getFeatureStore() {
267
            return (FeatureStore) this.wkRefStore.get();
268
        }
269 40435 jjdelcerro
270 41926 jjdelcerro
        public List getFeatureTypes() throws DataException {
271
            if (this.ftypes == null) {
272
                this.ftypes = Arrays
273
                        .asList(new FeatureType[]{this.ftTarget_non_editable});
274
            }
275
            return this.ftypes;
276
        }
277 40435 jjdelcerro
278 41926 jjdelcerro
        public FeatureType getSourceFeatureTypeFrom(
279
                FeatureType targetFeatureType) {
280
            EditableFeatureType orgType = ftSource.getEditable();
281
            Iterator iter = orgType.iterator();
282
            FeatureAttributeDescriptor attr;
283
            EditableFeatureAttributeDescriptor efad = null;
284 40435 jjdelcerro
285 41926 jjdelcerro
            while (iter.hasNext()) {
286
                attr = (FeatureAttributeDescriptor) iter.next();
287
                if (!attrInSourceToUse.contains(attr.getName())) {
288
                    if (attr instanceof EditableFeatureAttributeDescriptor) {
289
                        efad = (EditableFeatureAttributeDescriptor) attr;
290
                        if (efad.getOriginalName() != null
291
                                && !attrInSourceToUse.contains(efad.getOriginalName())) {
292
                            iter.remove();
293
                        }
294
                    } else {
295
                        iter.remove();
296
                    }
297
                }
298
            }
299
            return orgType.getNotEditableCopy();
300
        }
301 40435 jjdelcerro
302 41926 jjdelcerro
        public void setFeatureStore(FeatureStore featureStore) {
303
            this.wkRefStore = new WeakReference(featureStore);
304
        }
305 40435 jjdelcerro
306 41926 jjdelcerro
        public boolean isTransformsOriginalValues() {
307
            return false;
308
        }
309 40435 jjdelcerro
310 41926 jjdelcerro
    }
311 40435 jjdelcerro
312 41926 jjdelcerro
    public void restore(String id) {
313
        deleted.remove(id);
314
        deltaSize++;
315
    }
316 40435 jjdelcerro
317 41926 jjdelcerro
    public void restore(String id, int num) {
318
        if (added.containsKey(id)) {
319
            added.put(id, new Integer(num));
320
        } else {
321
            modifiedFromOriginal.put(id, new Integer(num));
322
        }
323
    }
324 40435 jjdelcerro
325 41926 jjdelcerro
    public boolean isDeleted(FeatureType type) {
326
        return deleted.contains(type.getId());
327
    }
328 40435 jjdelcerro
329 41926 jjdelcerro
    public boolean isDeleted(String id) {
330
        return deleted.contains(id);
331
    }
332 40435 jjdelcerro
333 41926 jjdelcerro
    public void clear() {
334
        added.clear();
335
        modifiedFromOriginal.clear();
336
        expansionAdapter.close();
337
        deleted.clear();// <FeatureID>
338
        deltaSize = 0;
339
    }
340 40435 jjdelcerro
341 41926 jjdelcerro
    public boolean hasChanges() {
342
        return added.size() > 0 || modifiedFromOriginal.size() > 0
343
                || deleted.size() > 0;
344
    }
345 40435 jjdelcerro
346 41926 jjdelcerro
    public Iterator newsIterator() {
347
        return added.values().iterator();
348
    }
349 40435 jjdelcerro
350 41926 jjdelcerro
    public boolean hasNews() {
351
        return !added.isEmpty();
352
    }
353 40435 jjdelcerro
354 41926 jjdelcerro
    public long getDeltaSize() {
355
        return deltaSize;
356
    }
357 40435 jjdelcerro
358 41926 jjdelcerro
    public FeatureType getOriginalFeatureType() {
359
        return originalType;
360
    }
361 40435 jjdelcerro
362 41926 jjdelcerro
    public DefaultFeatureStoreTransforms getTransforms() {
363
        return this.transforms;
364
    }
365 40435 jjdelcerro
366 41926 jjdelcerro
    public class FeatureTypeManagerFeatureStoreTransforms extends
367
            DefaultFeatureStoreTransforms {
368 40435 jjdelcerro
369 41926 jjdelcerro
        private FeatureTypeManagerFeatureStoreTransforms() {
370 40435 jjdelcerro
371 41926 jjdelcerro
        }
372 40435 jjdelcerro
373 41926 jjdelcerro
        protected void checkEditingMode() {
374
        }
375 40435 jjdelcerro
376 41926 jjdelcerro
        protected void notifyChangeToStore() {
377
        }
378 40435 jjdelcerro
379 41926 jjdelcerro
        public PersistentState getState() throws PersistenceException {
380
            // FIXME
381
            throw new UnsupportedOperationException();
382
        }
383 40435 jjdelcerro
384 41926 jjdelcerro
        public void loadState(PersistentState state)
385
                throws PersistenceException {
386
            // FIXME
387
            throw new UnsupportedOperationException();
388
        }
389 40435 jjdelcerro
390 41926 jjdelcerro
        public void loadFromState(PersistentState state) throws PersistenceException {
391
            // FIXME
392
            throw new UnsupportedOperationException();
393
        }
394 40435 jjdelcerro
395 41926 jjdelcerro
        public FeatureStoreTransform add(FeatureStoreTransform transform)
396
                throws DataException {
397
            if (!(transform instanceof UpdateFeatureTypeTransform)) {
398
                // FIXME
399
                throw new IllegalArgumentException();
400
            }
401
            return super.add(transform);
402
        }
403 40435 jjdelcerro
404 41926 jjdelcerro
    }
405 40435 jjdelcerro
406 41926 jjdelcerro
    public class FeatureTypesChangedItem implements FeatureTypeChanged {
407
408
        private FeatureType source;
409
        private FeatureType target;
410
411
        public FeatureTypesChangedItem(FeatureType source, FeatureType target) {
412
            this.source = source;
413
            this.target = target;
414
        }
415
416
        public FeatureType getSource() {
417
            return source;
418
        }
419
420
        public FeatureType getTarget() {
421
            return target;
422
        }
423
424
    }
425
426
    public Iterator getFeatureTypesChanged() throws DataException {
427
        // FIXME this don't work for Store.fType.size() > 1
428
        List list = new ArrayList();
429
        if (modifiedFromOriginal.size() > 0) {
430
            FeatureType src = this.getOriginalFeatureType();
431
            list.add(new FeatureTypesChangedItem(src, this.store
432
                    .getFeatureType(src.getId())));
433
        }
434
        return list.iterator();
435
    }
436
437 40435 jjdelcerro
}