Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.plugin / org.gvsig.app / org.gvsig.app.mainplugin / src / main / java / org / gvsig / app / extension / updatetable / UpdateTableProcessImpl.java @ 47046

History | View | Annotate | Download (11.1 KB)

1
/*
2
 * To change this license header, choose License Headers in Project Properties.
3
 * To change this template file, choose Tools | Templates
4
 * and open the template in the editor.
5
 */
6
package org.gvsig.app.extension.updatetable;
7

    
8
import java.util.List;
9
import org.gvsig.app.extension.updatetable.UpdateTableProcessParameters.ProcessFieldParameters;
10
import org.gvsig.expressionevaluator.Expression;
11
import org.gvsig.expressionevaluator.ExpressionUtils;
12
import org.gvsig.expressionevaluator.MutableSymbolTable;
13
import org.gvsig.expressionevaluator.SymbolTable;
14
import org.gvsig.fmap.dal.DALLocator;
15
import org.gvsig.fmap.dal.DataManager;
16
import org.gvsig.fmap.dal.exception.DataException;
17
import org.gvsig.fmap.dal.expressionevaluator.FeatureSymbolTable;
18
import org.gvsig.fmap.dal.feature.EditableFeature;
19
import org.gvsig.fmap.dal.feature.Feature;
20
import org.gvsig.fmap.dal.feature.FeatureQuery;
21
import org.gvsig.fmap.dal.feature.FeatureReference;
22
import org.gvsig.fmap.dal.feature.FeatureSet;
23
import org.gvsig.fmap.dal.feature.FeatureStore;
24
import org.gvsig.tools.dataTypes.DataTypeUtils;
25
import org.gvsig.tools.task.SimpleTaskStatus;
26
import org.slf4j.Logger;
27
import org.slf4j.LoggerFactory;
28
import org.gvsig.fmap.dal.DataTransaction;
29
import org.gvsig.tools.dispose.DisposeUtils;
30

    
31
/**
32
 *
33
 * @author jjdelcerro
34
 */
35
@SuppressWarnings("UseSpecificCatch")
36
public class UpdateTableProcessImpl implements UpdateTableProcess {
37

    
38
    protected final Logger LOGGER = LoggerFactory.getLogger(UpdateTableProcessImpl.class);
39

    
40
    private UpdateTableProcessParameters parameters;
41
    private SimpleTaskStatus status;
42
    private Runnable postprocess;
43
    private FeatureSymbolTable featureSymbolTable;
44
    private DataTransaction transaction;
45
    private MutableSymbolTable out;
46
    
47
    public UpdateTableProcessImpl() {
48
        
49
    }
50
    
51
    public UpdateTableProcessImpl(UpdateTableProcessParameters parameters, SimpleTaskStatus status, Runnable postprocess) {
52
        this();
53
        this.parameters = parameters;
54
        this.status = status;
55
        this.postprocess = postprocess;
56
    }
57

    
58
    @Override
59
    public void start() {
60
        Thread th = new Thread(
61
                () -> {
62
                    try {
63
                        run();
64
                    } catch (Exception ex) {
65
                        LOGGER.warn("Can't process table update.");
66
                    }
67
                },
68
                "UpdateTableProcess"
69
        );
70
        th.start();
71
    }
72

    
73
    @Override
74
    public void run() {
75
        try {
76
            DataManager dataManager = DALLocator.getDataManager();
77

    
78
            this.transaction = dataManager.createTransaction();
79
            this.transaction.begin();
80

    
81
            FeatureStore store = this.parameters.getStore();
82
            this.transaction.add(store, false);
83
            
84
            this.status.setTitle("Update table '" + store.getName() + "'");
85
            this.status.setIndeterminate();
86

    
87
            this.featureSymbolTable = dataManager.createFeatureSymbolTable();
88

    
89
            switch (this.parameters.getRowsToProcess()) {
90
                case UpdateTableProcessParameters.BATCHUPDATE_PROCESS_ALL:
91
                    update_all();
92
                    break;
93
                case UpdateTableProcessParameters.BATCHUPDATE_PROCESS_SELECTION:
94
                    update_selection();
95
                    break;
96
                case UpdateTableProcessParameters.BATCHUPDATE_PROCESS_EDITEDS:
97
                    update_editeds();
98
                    break;
99
            }
100
            if (this.status.isCancelled()) {
101
                abortEditing();
102
                DataTransaction.rollbackQuietly(this.transaction);
103
                this.status.message("Operation cancelled by user");
104
            } else {
105
                endEditing();
106
                this.transaction.commit();
107
                this.status.terminate();
108

    
109
                this.output();
110
                out.setVar("store", store);
111

    
112
                if (postprocess != null) {
113
                    postprocess.run();
114
                }
115
            }
116
            
117
        } catch (Exception ex) {
118
            DataTransaction.rollbackQuietly(this.transaction);
119
            this.status.abort();
120
            this.status.message("Can't update features");
121
                    
122
        } finally {
123
            DisposeUtils.dispose(this.transaction);
124
        }
125
    }
126

    
127
    public void update_editeds() throws DataException {
128
        FeatureStore store = this.parameters.getStore();
129
        Expression filter = this.parameters.getFilter();
130
        List<FeatureReference> set = store.getEditedFeatures();
131
        if( set.isEmpty() ) {
132
            return;
133
        }
134
        this.beginEditing();
135
        long rows = set.size();
136
        this.status.setRangeOfValues(0, rows);
137

    
138
        for (FeatureReference featureReferfence : set) {
139
            this.status.incrementCurrentValue();
140
            if (this.status.isCancellationRequested()) {
141
                this.status.cancel();
142
                this.abortEditing();
143
                return;
144
            }
145
            Feature feature = featureReferfence.getFeature();
146
            this.featureSymbolTable.setFeature(feature);
147
            boolean sholdProcessFeature = DataTypeUtils.toBoolean(filter.execute(featureSymbolTable), false);
148
            if (!sholdProcessFeature) {
149
                continue;
150
            }
151

    
152
            EditableFeature editable_feature = feature.getEditable();
153
            process_feature(editable_feature);
154
            store.update(editable_feature);
155
            restart_editing();
156
        }
157
        this.endEditing();
158
    }
159

    
160
    public void update_selection() throws DataException {
161
        FeatureStore store = this.parameters.getStore();
162
        Expression filter = this.parameters.getFilter();
163
        FeatureSet set = store.getFeatureSelection();
164
        this.beginEditing();
165
        long rows = set.getSize();
166
        this.status.setRangeOfValues(0, rows);
167

    
168
        for (Feature feature : set) {
169
            this.status.incrementCurrentValue();
170
            if (this.status.isCancellationRequested()) {
171
                this.status.cancel();
172
                this.abortEditing();
173
                return;
174
            }
175

    
176
            this.featureSymbolTable.setFeature(feature);
177
            if( filter!=null ) {
178
                boolean sholdProcessFeature = DataTypeUtils.toBoolean(filter.execute(featureSymbolTable), false);
179
                if (!sholdProcessFeature) {
180
                    continue;
181
                }
182
            }
183

    
184
            EditableFeature editable_feature = feature.getEditable();
185
            process_feature(editable_feature);
186
            set.update(editable_feature);
187
            restart_editing();
188
        }
189
        this.endEditing();
190
    }
191

    
192
    public void update_all() throws DataException {
193
        FeatureStore store = this.parameters.getStore();
194
        Expression filter = this.parameters.getFilter();
195
        
196
        FeatureQuery query = store.createFeatureQuery(filter);
197
        FeatureSet set = store.getFeatureSet(query);
198
        this.transaction.add(set);
199
        
200
        this.beginEditing();
201
        long rows = set.getSize();
202
        this.status.setRangeOfValues(0, rows);
203

    
204
        for (Feature feature : set) {
205
            this.status.incrementCurrentValue();
206
            if (this.status.isCancellationRequested()) {
207
                this.status.cancel();
208
                this.abortEditing();
209
                return;
210
            }
211
            EditableFeature editable_feature = feature.getEditable();
212
            process_feature(editable_feature);
213
            set.update(editable_feature);
214
            restart_editing();
215
        }
216
        this.endEditing();
217
    }
218

    
219
    private void process_feature(EditableFeature feature) {
220
        for (ProcessFieldParameters field : parameters) {
221
            if (!field.isUpdate()) {
222
                continue;
223
            }
224
            Expression expression = field.getExpression();
225
            if (expression == null || expression.isPhraseEmpty()) {
226
                continue;
227
            }
228
            this.featureSymbolTable.setFeature(feature);
229
            Object x = expression.execute(this.featureSymbolTable);
230
            feature.set(field.getName(), x);
231
        }
232
    }
233

    
234
    private void beginEditing() throws DataException {
235
        if( this.parameters.getRowsToProcess()==UpdateTableProcessParameters.BATCHUPDATE_PROCESS_EDITEDS ) {
236
            // Si hemos de procesar las editadas, mantenemos el modo de edicion
237
            // que hubiese, que deberia ser MODE_FULLEDIT.
238
            return;
239
        }
240
        if (!this.parameters.isBeginEditIfNeed()) {
241
            return;
242
        }
243
        FeatureStore store = this.parameters.getStore();
244
        if (store.getMode() != FeatureStore.MODE_QUERY) {
245
            if (this.parameters.isFinishAndRestarEdit()) {
246
                store.finishEditing();
247
            }
248
        }
249
        store.edit(this.parameters.getEditMode());
250
    }
251

    
252
    private void endEditing() throws DataException {
253
        if (this.parameters.isFinishEditAfterTerminate()) {
254
            FeatureStore store = this.parameters.getStore();
255
            if( store.getMode() != FeatureStore.MODE_QUERY ) {
256
                store.finishEditing();
257
            }
258
        }
259
    }
260

    
261
    private void abortEditing() throws DataException {
262
        if (this.parameters.isFinishEditAfterTerminate()) {
263
            FeatureStore store = this.parameters.getStore();
264
            if( store.getMode() != FeatureStore.MODE_QUERY ) {
265
                store.cancelEditing();
266
            }
267
        }
268
    }
269

    
270
    private void restart_editing() throws DataException {
271
        if( this.parameters.getRowsToProcess()==UpdateTableProcessParameters.BATCHUPDATE_PROCESS_EDITEDS ) {
272
            // Si estamos procesando las editadas no reiniciamos la edicion nunca
273
            // ya que perderiamos las features editadas.
274
            return;
275
        }
276
        int n = this.parameters.getFinishAndRestarEditEach();
277
        if (n < 1) {
278
            return;
279
        }
280
        FeatureStore store = this.parameters.getStore();
281
        switch (store.getMode()) {
282
            case FeatureStore.MODE_PASS_THROUGH:
283
            case FeatureStore.MODE_APPEND:
284
                return;
285
            case FeatureStore.MODE_FULLEDIT:
286
            default:
287
                break;
288
        }
289
        if (store.getMode() != FeatureStore.MODE_FULLEDIT) {
290
            return;
291
        }
292
        if (store.getPendingChangesCount() < n) {
293
            return;
294
        }
295
        store.finishEditing();
296
        store.edit(this.parameters.getEditMode());
297
    }
298

    
299
    @Override
300
    public UpdateTableProcess parameters(UpdateTableProcessParameters params) {
301
        this.parameters = params;
302
        return this;
303
    }
304

    
305
    @Override
306
    public UpdateTableProcess status(SimpleTaskStatus taskStatus) {
307
        this.status = taskStatus;
308
        return this;
309
    }
310

    
311
    @Override
312
    public UpdateTableProcess postProcess(Runnable postProcess) {
313
        this.postprocess = postProcess;
314
        return this;
315
    }
316

    
317
    @Override
318
    public UpdateTableProcessParameters createParameters() {
319
        return new UpdateTableProcessParametersImpl();
320
    }
321

    
322
    @Override
323
    public SymbolTable output() {
324
        if( this.out == null ) {
325
            this.out = ExpressionUtils.createSymbolTable();
326
        }
327
        return this.out;
328
    }
329
    
330
    
331

    
332
}