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

History | View | Annotate | Download (15.1 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 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
 *
11
 * 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
 *
16
 * 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
 *
20
 * For any additional information, do not hesitate to contact us at info AT
21
 * gvsig.com, or visit our website www.gvsig.com.
22
 */
23
package org.gvsig.fmap.dal.feature.impl.editing.memory;
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
import java.util.Map;
32

    
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
import org.gvsig.fmap.dal.feature.impl.DefaultFeatureStoreTransforms;
44
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
    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
    private int deltaSize = 0;
59
    private boolean first = true;
60
    private FeatureType originalType = null;
61

    
62
    public FeatureTypeManager(FeatureStore store) {
63
        this.expansionAdapter = new MemoryExpansionAdapter();
64
        this.store = store;
65
        this.transforms = new FeatureTypeManagerFeatureStoreTransforms();
66
        this.transforms.setFeatureStore(store);
67
    }
68

    
69
    public void dispose() {
70
        this.expansionAdapter.close();
71
        this.deleted.clear();
72
        this.transforms.clear();
73
        this.added.clear();
74
        this.modifiedFromOriginal.clear();
75
    }
76

    
77
    public FeatureType getType(String id) throws DataException {
78
        Integer num = added.get(id);
79
        if (num == null) {
80
            num = modifiedFromOriginal.get(id);
81
            if (num == null) {
82
                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

    
97
    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

    
107
        if (added.containsKey(id)) {
108
            oldNum = added.get(id);
109
            added.put(id, num);
110
        } else {
111
            if (modifiedFromOriginal.get(id) != null) {
112
                oldNum = modifiedFromOriginal.get(id);
113
            }
114
            modifiedFromOriginal.put(id, num);
115
        }
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
        private final FeatureType ftSource;
130

    
131
        private EditableFeatureType ftTarget_editable;
132
        private final FeatureType ftTarget_non_editable;
133

    
134
        private WeakReference wkRefStore;
135
        private List ftypes = null;
136
        private List attrInSourceToUse;
137

    
138
        UpdateFeatureTypeTransform(FeatureStore featureStore,
139
                FeatureType ftSource, FeatureType ftTarget) {
140
            this.ftSource = ftSource;
141

    
142
            if (ftTarget instanceof EditableFeatureType) {
143

    
144
                ftTarget_editable = (EditableFeatureType) ftTarget;
145
                ftTarget_non_editable = ftTarget_editable.getNotEditableCopy();
146
            } else {
147
                ftTarget_non_editable = ftTarget;
148
            }
149

    
150
            this.wkRefStore = new WeakReference(featureStore);
151
            this.initializeAttributesToUse();
152
        }
153

    
154
        private void initializeAttributesToUse() {
155
            attrInSourceToUse = new ArrayList();
156

    
157
            Iterator iter;
158
            if (ftTarget_editable != null) {
159
                iter = ftTarget_editable.iterator();
160
            } else {
161
                iter = ftTarget_non_editable.iterator();
162
            }
163

    
164
            FeatureAttributeDescriptor tAttr, sAttr;
165
            EditableFeatureAttributeDescriptor ead;
166
            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
        @Override
196
        public void setUp() throws Exception {
197
            
198
        }
199

    
200
        @Override
201
        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
            String s_name;
213

    
214
            /*
215
             * field name in target feature (the same as in source
216
             * except if renamed)
217
             */
218
            String t_name;
219

    
220
            EditableFeatureAttributeDescriptor eatd;
221
            while (iter.hasNext()) {
222
                tAttr = (FeatureAttributeDescriptor) iter.next();
223

    
224
                if (ftTarget_editable != null) {
225
                    /*
226
                     * If target FT is editable, try to get original name
227
                     */
228
                    t_name = tAttr.getName();
229
                    s_name = t_name;
230
                    tAttr_edi = ftTarget_editable.getAttributeDescriptor(t_name);
231
                    if (tAttr_edi instanceof EditableFeatureAttributeDescriptor) {
232
                        eatd = (EditableFeatureAttributeDescriptor) tAttr_edi;
233
                        s_name = eatd.getOriginalName();
234
                    }
235

    
236
                    /*
237
                     * If not found, use normal name
238
                     */
239
                    if (s_name == null) {
240
                        s_name = tAttr.getName();
241
                    }
242
                } else {
243
                    /*
244
                     * If target FT is not editable, use normal name
245
                     */
246
                    t_name = tAttr.getName();
247
                    s_name = t_name;
248
                }
249

    
250
                srcAtt = source.getType().getAttributeDescriptor(s_name);
251

    
252
                if (srcAtt != null
253
                        && /*
254
                         * This prevents the case when user has removed field and
255
                         * added new field with same name and different type.
256
                         * In that case, value will be the default value (else below)
257
                         */ srcAtt.getType() == tAttr.getType()) {
258

    
259
                    target.set(t_name, source.get(s_name));
260

    
261
                } else {
262
                    target.set(t_name, tAttr.getDefaultValue());
263
                }
264
            }
265
        }
266

    
267
        @Override
268
        public FeatureType getDefaultFeatureType() throws DataException {
269
            return this.ftTarget_non_editable;
270
        }
271

    
272
        @Override
273
        public FeatureStore getFeatureStore() {
274
            return (FeatureStore) this.wkRefStore.get();
275
        }
276

    
277
        @Override
278
        public List getFeatureTypes() throws DataException {
279
            if (this.ftypes == null) {
280
                this.ftypes = Arrays
281
                        .asList(new FeatureType[]{this.ftTarget_non_editable});
282
            }
283
            return this.ftypes;
284
        }
285

    
286
        @Override
287
        public FeatureType getSourceFeatureTypeFrom(
288
                FeatureType targetFeatureType) {
289
            EditableFeatureType orgType = ftSource.getEditable();
290
            Iterator iter = orgType.iterator();
291
            FeatureAttributeDescriptor attr;
292
            EditableFeatureAttributeDescriptor efad;
293

    
294
            while (iter.hasNext()) {
295
                attr = (FeatureAttributeDescriptor) iter.next();
296
                if (!attrInSourceToUse.contains(attr.getName())) {
297
                    if (attr instanceof EditableFeatureAttributeDescriptor) {
298
                        efad = (EditableFeatureAttributeDescriptor) attr;
299
                        if (efad.getOriginalName() != null
300
                                && !attrInSourceToUse.contains(efad.getOriginalName())) {
301
                            iter.remove();
302
                        }
303
                    } else {
304
                        iter.remove();
305
                    }
306
                }
307
            }
308
            return orgType.getNotEditableCopy();
309
        }
310

    
311
        @Override
312
        public void setFeatureStore(FeatureStore featureStore) {
313
            this.wkRefStore = new WeakReference(featureStore);
314
        }
315

    
316
        @Override
317
        public boolean isTransformsOriginalValues() {
318
            return false;
319
        }
320

    
321
    }
322

    
323
    public void restore(String id) {
324
        deleted.remove(id);
325
        deltaSize++;
326
    }
327

    
328
    public void restore(String id, int num) {
329
        if (added.containsKey(id)) {
330
            added.put(id, num);
331
        } else {
332
            modifiedFromOriginal.put(id, num);
333
        }
334
    }
335

    
336
    public boolean isDeleted(FeatureType type) {
337
        return deleted.contains(type.getId());
338
    }
339

    
340
    public boolean isDeleted(String id) {
341
        return deleted.contains(id);
342
    }
343

    
344
    public void clear() {
345
        added.clear();
346
        modifiedFromOriginal.clear();
347
        expansionAdapter.close();
348
        deleted.clear();
349
        deltaSize = 0;
350
    }
351

    
352
    public boolean hasChanges() {
353
        return added.size() > 0 || modifiedFromOriginal.size() > 0
354
                || deleted.size() > 0;
355
    }
356

    
357
    public Iterator newsIterator() {
358
        return added.values().iterator();
359
    }
360

    
361
    public boolean hasNews() {
362
        return !added.isEmpty();
363
    }
364

    
365
    public long getDeltaSize() {
366
        return deltaSize;
367
    }
368

    
369
    public FeatureType getOriginalFeatureType() {
370
        return originalType;
371
    }
372

    
373
    public DefaultFeatureStoreTransforms getTransforms() {
374
        return this.transforms;
375
    }
376

    
377
    public class FeatureTypeManagerFeatureStoreTransforms extends
378
            DefaultFeatureStoreTransforms {
379

    
380
        private FeatureTypeManagerFeatureStoreTransforms() {
381

    
382
        }
383

    
384
        @Override
385
        protected void checkEditingMode() {
386
        }
387

    
388
        @Override
389
        protected void notifyChangeToStore() {
390
        }
391

    
392
        public PersistentState getState() throws PersistenceException {
393
            // FIXME
394
            throw new UnsupportedOperationException();
395
        }
396

    
397
        public void loadState(PersistentState state)
398
                throws PersistenceException {
399
            // FIXME
400
            throw new UnsupportedOperationException();
401
        }
402

    
403
        @Override
404
        public void loadFromState(PersistentState state) throws PersistenceException {
405
            // FIXME
406
            throw new UnsupportedOperationException();
407
        }
408

    
409
        @Override
410
        public FeatureStoreTransform add(FeatureStoreTransform transform)
411
                throws DataException {
412
            if (!(transform instanceof UpdateFeatureTypeTransform)) {
413
                // FIXME
414
                throw new IllegalArgumentException();
415
            }
416
            return super.add(transform);
417
        }
418

    
419
    }
420

    
421
    public class FeatureTypesChangedItem implements FeatureTypeChanged {
422

    
423
        private final FeatureType source;
424
        private final FeatureType target;
425

    
426
        public FeatureTypesChangedItem(FeatureType source, FeatureType target) {
427
            this.source = source;
428
            this.target = target;
429
        }
430

    
431
        @Override
432
        public FeatureType getSource() {
433
            return source;
434
        }
435

    
436
        @Override
437
        public FeatureType getTarget() {
438
            return target;
439
        }
440

    
441
    }
442

    
443
    public Iterator getFeatureTypesChanged() throws DataException {
444
        // FIXME this don't work for Store.fType.size() > 1
445
        List list = new ArrayList();
446
        if (modifiedFromOriginal.size() > 0) {
447
            FeatureType src = this.getOriginalFeatureType();
448
            list.add(new FeatureTypesChangedItem(src, this.store
449
                    .getFeatureType(src.getId())));
450
        }
451
        return list.iterator();
452
    }
453

    
454
}