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

History | View | Annotate | Download (14.9 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;
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
    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

    
59
    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

    
67
    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

    
75
    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

    
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

    
94
        FeatureType type = (FeatureType) expansionAdapter.getObject(num);
95
        return type;
96
    }
97

    
98
    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

    
108
        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
        private EditableFeatureType ftTarget_editable;
133
        private FeatureType ftTarget_non_editable;
134

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

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

    
143
            if (ftTarget instanceof EditableFeatureType) {
144

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

    
151
            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
        @Override
197
        public void setUp() throws Exception {
198
            
199
        }
200

    
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 = null;
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
        public FeatureType getDefaultFeatureType() throws DataException {
268
            return this.ftTarget_non_editable;
269
        }
270

    
271
        public FeatureStore getFeatureStore() {
272
            return (FeatureStore) this.wkRefStore.get();
273
        }
274

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

    
283
        public FeatureType getSourceFeatureTypeFrom(
284
                FeatureType targetFeatureType) {
285
            EditableFeatureType orgType = ftSource.getEditable();
286
            Iterator iter = orgType.iterator();
287
            FeatureAttributeDescriptor attr;
288
            EditableFeatureAttributeDescriptor efad = null;
289

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

    
307
        public void setFeatureStore(FeatureStore featureStore) {
308
            this.wkRefStore = new WeakReference(featureStore);
309
        }
310

    
311
        public boolean isTransformsOriginalValues() {
312
            return false;
313
        }
314

    
315
    }
316

    
317
    public void restore(String id) {
318
        deleted.remove(id);
319
        deltaSize++;
320
    }
321

    
322
    public void restore(String id, int num) {
323
        if (added.containsKey(id)) {
324
            added.put(id, new Integer(num));
325
        } else {
326
            modifiedFromOriginal.put(id, new Integer(num));
327
        }
328
    }
329

    
330
    public boolean isDeleted(FeatureType type) {
331
        return deleted.contains(type.getId());
332
    }
333

    
334
    public boolean isDeleted(String id) {
335
        return deleted.contains(id);
336
    }
337

    
338
    public void clear() {
339
        added.clear();
340
        modifiedFromOriginal.clear();
341
        expansionAdapter.close();
342
        deleted.clear();// <FeatureID>
343
        deltaSize = 0;
344
    }
345

    
346
    public boolean hasChanges() {
347
        return added.size() > 0 || modifiedFromOriginal.size() > 0
348
                || deleted.size() > 0;
349
    }
350

    
351
    public Iterator newsIterator() {
352
        return added.values().iterator();
353
    }
354

    
355
    public boolean hasNews() {
356
        return !added.isEmpty();
357
    }
358

    
359
    public long getDeltaSize() {
360
        return deltaSize;
361
    }
362

    
363
    public FeatureType getOriginalFeatureType() {
364
        return originalType;
365
    }
366

    
367
    public DefaultFeatureStoreTransforms getTransforms() {
368
        return this.transforms;
369
    }
370

    
371
    public class FeatureTypeManagerFeatureStoreTransforms extends
372
            DefaultFeatureStoreTransforms {
373

    
374
        private FeatureTypeManagerFeatureStoreTransforms() {
375

    
376
        }
377

    
378
        protected void checkEditingMode() {
379
        }
380

    
381
        protected void notifyChangeToStore() {
382
        }
383

    
384
        public PersistentState getState() throws PersistenceException {
385
            // FIXME
386
            throw new UnsupportedOperationException();
387
        }
388

    
389
        public void loadState(PersistentState state)
390
                throws PersistenceException {
391
            // FIXME
392
            throw new UnsupportedOperationException();
393
        }
394

    
395
        public void loadFromState(PersistentState state) throws PersistenceException {
396
            // FIXME
397
            throw new UnsupportedOperationException();
398
        }
399

    
400
        public FeatureStoreTransform add(FeatureStoreTransform transform)
401
                throws DataException {
402
            if (!(transform instanceof UpdateFeatureTypeTransform)) {
403
                // FIXME
404
                throw new IllegalArgumentException();
405
            }
406
            return super.add(transform);
407
        }
408

    
409
    }
410

    
411
    public class FeatureTypesChangedItem implements FeatureTypeChanged {
412

    
413
        private FeatureType source;
414
        private FeatureType target;
415

    
416
        public FeatureTypesChangedItem(FeatureType source, FeatureType target) {
417
            this.source = source;
418
            this.target = target;
419
        }
420

    
421
        public FeatureType getSource() {
422
            return source;
423
        }
424

    
425
        public FeatureType getTarget() {
426
            return target;
427
        }
428

    
429
    }
430

    
431
    public Iterator getFeatureTypesChanged() throws DataException {
432
        // FIXME this don't work for Store.fType.size() > 1
433
        List list = new ArrayList();
434
        if (modifiedFromOriginal.size() > 0) {
435
            FeatureType src = this.getOriginalFeatureType();
436
            list.add(new FeatureTypesChangedItem(src, this.store
437
                    .getFeatureType(src.getId())));
438
        }
439
        return list.iterator();
440
    }
441

    
442
}