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 / DefaultFeatureStoreTransforms.java

History | View | Annotate | Download (14.5 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.ArrayList;
27
import java.util.Collections;
28
import java.util.Iterator;
29
import java.util.List;
30
import java.util.ListIterator;
31

    
32
import org.gvsig.fmap.dal.exception.DataException;
33
import org.gvsig.fmap.dal.feature.EditableFeature;
34
import org.gvsig.fmap.dal.feature.EditableFeatureAttributeDescriptor;
35
import org.gvsig.fmap.dal.feature.EditableFeatureType;
36
import org.gvsig.fmap.dal.feature.Feature;
37
import org.gvsig.fmap.dal.feature.FeatureStore;
38
import org.gvsig.fmap.dal.feature.FeatureStoreNotification;
39
import org.gvsig.fmap.dal.feature.FeatureStoreTransform;
40
import org.gvsig.fmap.dal.feature.FeatureStoreTransforms;
41
import org.gvsig.fmap.dal.feature.FeatureType;
42
import org.gvsig.fmap.dal.feature.spi.FeatureProvider;
43
import org.gvsig.tools.ToolsLocator;
44
import org.gvsig.tools.dynobject.DynStruct;
45
import org.gvsig.tools.dynobject.exception.DynFieldNotFoundException;
46
import org.gvsig.tools.persistence.Persistent;
47
import org.gvsig.tools.persistence.PersistentState;
48
import org.gvsig.tools.persistence.exception.PersistenceException;
49
import org.slf4j.Logger;
50
import org.slf4j.LoggerFactory;
51
import org.gvsig.fmap.dal.feature.FeatureExtraColumns;
52

    
53
public class DefaultFeatureStoreTransforms
54
    implements FeatureStoreTransforms,
55
    Persistent {
56

    
57
    private static final Logger LOGGER = LoggerFactory.getLogger(DefaultFeatureStoreTransforms.class);
58
    
59
    private DefaultFeatureStore store;
60
    private List<FeatureStoreTransform> transforms;
61
    private Boolean isTramsformValues;
62
    private TransformTemporalList lastTransformStack;
63

    
64
    public DefaultFeatureStoreTransforms() {
65
        this.store = null;
66
        this.transforms = new ArrayList();
67
        this.isTramsformValues = false;
68
    }
69

    
70
    public DefaultFeatureStoreTransforms(DefaultFeatureStore store) {
71
        this.store = store;
72
        this.transforms = new ArrayList();
73
    }
74

    
75
    protected void checkEditingMode() {
76
        if( store == null || store.getMode() != FeatureStore.MODE_QUERY ) {
77
            throw new IllegalStateException();
78
        }
79
    }
80

    
81
    protected void notifyChangeToStore() {
82
        this.store.notifyChange(FeatureStoreNotification.TRANSFORM_CHANGE);
83
    }
84

    
85
    @Override
86
    public FeatureStoreTransform add(FeatureStoreTransform transform)
87
        throws DataException {
88
        checkEditingMode();
89
        try {
90
            transform.setUp();
91
        } catch (Exception ex) {
92
            throw new RuntimeException("Can't set up transformation.", ex);
93
        }
94
        if( transform.getDefaultFeatureType() != null ) {
95
            if( !transform.getFeatureTypes().contains(transform.getDefaultFeatureType()) ) {
96
                throw new IllegalArgumentException(); // FIXME: Add specific type
97
            }
98
            this.transforms.add(transform);
99
            transform.setFeatureStore(store);
100
            transform.setSourceMetadata(this.store.metadata);
101
            transform.apply(this.store);
102
            this.notifyChangeToStore();
103
            if( this.isTramsformValues == null || (!this.isTramsformValues) ) {
104
                if( transform.isTransformsOriginalValues() ) {
105
                    this.isTramsformValues = true;
106
                }
107

    
108
            }
109
        }
110

    
111
        return transform;
112
    }
113

    
114
    @Override
115
    public void clear() {
116
        checkEditingMode();
117
        this.transforms.clear();
118
        this.notifyChangeToStore();
119
        this.isTramsformValues = Boolean.FALSE;
120
    }
121

    
122
    @Override
123
    public FeatureStoreTransform getTransform(int index) {
124
        return (FeatureStoreTransform) this.transforms.get(index);
125
    }
126

    
127
    @Override
128
    public Iterator<FeatureStoreTransform> iterator() {
129
        return Collections.unmodifiableList(transforms).iterator();
130
    }
131

    
132
    @Override
133
    public Object remove(int index) {
134
        checkEditingMode();
135
        FeatureStoreTransform trans = this.transforms.remove(index);
136
        trans.revoke(this.store);
137

    
138
        this.notifyChangeToStore();
139
        this.isTramsformValues = null;
140
        return trans;
141
    }
142

    
143
    @Override
144
    public boolean remove(FeatureStoreTransform transform) {
145
        checkEditingMode();
146
        boolean removed = this.transforms.remove(transform);
147
        if( removed ) {
148
            this.notifyChangeToStore();
149

    
150
        }
151
        this.isTramsformValues = null;
152
        return removed;
153

    
154
    }
155

    
156
    @Override
157
    public int size() {
158
        return this.transforms.size();
159
    }
160

    
161
    @Override
162
    public boolean isEmpty() {
163
        return this.transforms.isEmpty();
164
    }
165

    
166
    private class TransformTemporalListElement {
167

    
168
        public FeatureStoreTransform transform = null;
169
        public FeatureType targetFeatureType = null;
170
    }
171

    
172
    private class TransformTemporalList
173
        extends ArrayList {
174

    
175
        /**
176
         *
177
         */
178
        private static final long serialVersionUID = 1677014259279944000L;
179
        private FeatureType targetFType;
180

    
181
        @Override
182
        public boolean add(Object arg0) {
183
            if( this.isEmpty() ) {
184
                targetFType = ((TransformTemporalListElement) arg0).targetFeatureType;
185
            }
186
            return super.add(arg0);
187
        }
188

    
189
    }
190

    
191
    private TransformTemporalList getTransformTemporalList(FeatureType targetFeatureType) {
192
        if( this.lastTransformStack == null
193
            || this.lastTransformStack.size() != this.transforms.size()
194
            || !(this.lastTransformStack.targetFType.equals(targetFeatureType)) ) {
195
            TransformTemporalList result = new TransformTemporalList();
196
            TransformTemporalListElement item;
197
            FeatureType nextFType = targetFeatureType;
198

    
199
            for( int i = transforms.size() - 1; i > -1; i-- ) {
200
                item = new TransformTemporalListElement();
201
                item.transform = (FeatureStoreTransform) transforms.get(i);
202
                item.targetFeatureType = nextFType;
203
                nextFType = item.transform.getSourceFeatureTypeFrom(item.targetFeatureType);
204
                result.add(item);
205
            }
206
            this.lastTransformStack = result;
207
        }
208
        return this.lastTransformStack;
209
    }
210

    
211
    public Feature applyTransform(DefaultFeature source,
212
        FeatureType targetFeatureType)
213
        throws DataException {
214
        if( this.transforms.isEmpty() ) {
215
            return source;
216
        }
217

    
218
        TransformTemporalList stack = this
219
            .getTransformTemporalList(targetFeatureType);
220
        TransformTemporalListElement item;
221
        FeatureProvider targetData;
222
        DefaultEditableFeature target;
223
        ListIterator iterator = stack.listIterator(stack.size());
224
        FeatureType tft = null;
225

    
226
        while( iterator.hasPrevious() ) {
227
            item = (TransformTemporalListElement) iterator.previous();
228

    
229
            tft = item.targetFeatureType;
230
            if( tft instanceof EditableFeatureType ) {
231
                /*
232
                             * Must be non-editable to create 
233
                             * DefaultFeatureProvider
234
                 */
235
                tft = ((EditableFeatureType) tft).getNotEditableCopy();
236
            }
237

    
238
            targetData = this.store.createDefaultFeatureProvider(tft);
239
            targetData.setNew(true);
240
            targetData.setOID(source.getData().getOID());
241
            target = new DefaultEditableFeature(this.store, targetData);
242
            item.transform.applyTransform(source, target);
243
            targetData.setNew(source.getData().isNew());
244
            target.setInserted(source.isInserted());
245
            source = (DefaultFeature) target.getNotEditableCopy();
246
        }
247

    
248
        return source;
249

    
250
    }
251

    
252
    public FeatureType getSourceFeatureTypeFrom(FeatureType targetFeatureType) {
253
        FeatureType tmpFType = targetFeatureType;
254

    
255
        for( int i = transforms.size() - 1; i > -1; i-- ) {
256
            FeatureStoreTransform transform = transforms.get(i);
257
            tmpFType = transform.getSourceFeatureTypeFrom(tmpFType);
258
        }
259
        // se mantienen
260
        List<EditableFeatureAttributeDescriptor> extraCols = targetFeatureType.getExtraColumns().getColumns();
261
        if (extraCols!=null & !extraCols.isEmpty()) {
262
            FeatureExtraColumns tmpExtraCols = tmpFType.getExtraColumns();
263
            tmpExtraCols.merge(targetFeatureType.getExtraColumns());
264
            ((DefaultFeatureType) tmpFType).setExtraColumn(tmpExtraCols);
265
        } 
266
        return tmpFType;
267
    }
268

    
269
    public FeatureType getDefaultFeatureType() throws DataException {
270
        if( this.transforms.isEmpty() ) {
271
            return null;
272
        }
273
        FeatureStoreTransform transform = this.transforms.get(this.transforms.size() - 1);
274
        return transform.getDefaultFeatureType();
275
    }
276

    
277
    public List<FeatureType> getFeatureTypes() throws DataException {
278
        if( this.transforms.isEmpty() ) {
279
            return null;
280
        }
281
        FeatureStoreTransform transform = this.transforms.get(this.transforms.size() - 1);
282
        return transform.getFeatureTypes();
283
    }
284

    
285
    public FeatureStore getFeatureStore() {
286
        return this.store;
287
    }
288

    
289
    public void setFeatureStore(FeatureStore featureStore) {
290
        if( this.store != null ) {
291
            throw new IllegalStateException();
292
        }
293
        this.store = (DefaultFeatureStore) featureStore;
294
        for( FeatureStoreTransform transform : this ) {
295
            transform.setFeatureStore(featureStore);
296
        }
297
    }
298
    
299
    public void setStoreForClone(FeatureStore featureStore) {
300
        this.store = (DefaultFeatureStore) featureStore;
301
    }
302

    
303
    @Override
304
    public boolean isTransformsOriginalValues() {
305
        if( this.isTramsformValues == null ) {
306
            this.isTramsformValues = false;
307
            for( FeatureStoreTransform transform : this ) {
308
                if( transform.isTransformsOriginalValues() ) {
309
                    this.isTramsformValues = true;
310
                    break;
311
                }
312
            }
313
        }
314
        return this.isTramsformValues;
315
    }
316

    
317
    public FeatureType getFeatureType(String featureTypeId)
318
        throws DataException {
319
        if( this.transforms.isEmpty() ) {
320
            return null;
321
        }
322
        if( featureTypeId == null ) {
323
            return this.getDefaultFeatureType();
324
        }
325
        for( FeatureType fType : (List<FeatureType>) this.getFeatureTypes() ) {
326
            
327
        } 
328
        Iterator iter = this.getFeatureTypes().iterator();
329
        FeatureType fType;
330
        while( iter.hasNext() ) {
331
            fType = (FeatureType) iter.next();
332
            if( fType.getId().equals(featureTypeId) ) {
333
                return fType;
334
            }
335
        }
336
        return null;
337
    }
338

    
339
    @Override
340
    public void saveToState(PersistentState state) throws PersistenceException {
341
        // state.set("store", store);
342
        state.set("isTramsformValues", this.isTramsformValues);
343
        state.set("transforms", this.transforms);
344
    }
345

    
346
    @Override
347
    public void loadFromState(PersistentState state)
348
        throws PersistenceException {
349
        this.isTramsformValues = (Boolean) state.get("isTramsformValues");
350
        this.transforms = new ArrayList();
351
        List<FeatureStoreTransform> x = (List<FeatureStoreTransform>) state.get("transforms");
352
        this.transforms.addAll(x);
353
        // this.store = (DefaultFeatureStore) state.get("store");
354
    }
355

    
356
    public static void registerPersistent() {
357
        DynStruct definition = ToolsLocator.getPersistenceManager().addDefinition(
358
            DefaultFeatureStoreTransforms.class,
359
            "DefaultFeatureStoreTransforms",
360
            "DefaultFeatureStoreTransforms Persistent definition",
361
            null,
362
            null
363
        );
364

    
365
        definition.addDynFieldBoolean("isTramsformValues").setMandatory(false);
366
        definition.addDynFieldList("transforms").setClassOfItems(FeatureStoreTransform.class).setMandatory(true);
367
        definition.addDynFieldObject("store").setClassOfValue(FeatureStore.class).setMandatory(false);
368

    
369
    }
370

    
371
    public Object getDynValue(String name) throws DynFieldNotFoundException {
372
        if( !this.transforms.isEmpty() ) {
373
            for (int i = this.transforms.size() - 1; i >= 0; i--) {
374
                FeatureStoreTransform transform = transforms.get(i);
375
                if( transform!=null && transform.hasDynValue(name) ) {
376
                    Object value;
377
                    try {
378
                        value = transform.getDynValue(name);
379
                        if( value!=null ) {
380
                            return value;
381
                        }
382
                    } catch(Exception ex) {
383
                        LOGGER.warn("Cant retrieve value of '"+name+ "' in transform '"+transform.getName()+"'.", ex);
384
                    }
385
                }
386
            }
387
        }
388
        return null;
389
    }
390

    
391
    public void setDynValue(String name, Object value) throws DynFieldNotFoundException {
392
        if( !this.transforms.isEmpty() ) {
393
            FeatureStoreTransform transform = (FeatureStoreTransform) transforms.get(this.transforms.size() - 1);
394
            transform.setDynValue(name, value);
395
        }
396
    }
397

    
398
    public boolean hasDynValue(String name) {
399
        if( !this.transforms.isEmpty() ) {
400
            for (int i = this.transforms.size() - 1; i >= 0; i--) {
401
                FeatureStoreTransform transform = transforms.get(i);                
402
                if( transform.hasDynValue(name) ) {
403
                    return true;
404
                }
405
            }
406
        }
407
        return false;
408
    }
409

    
410
    @Override
411
    public Object clone() throws CloneNotSupportedException {
412
        DefaultFeatureStoreTransforms cloned = (DefaultFeatureStoreTransforms) super.clone();
413
        cloned.transforms = new ArrayList();
414
        for( FeatureStoreTransform transform : transforms ) {
415
            cloned.transforms.add((FeatureStoreTransform) transform.clone());
416
        }
417
        cloned.lastTransformStack = null;
418
        return cloned;
419
    }
420

    
421
}