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

History | View | Annotate | Download (13.2 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 java.util.function.Predicate;
10
import org.gvsig.app.extension.updatetable.UpdateTableProcessParameters.ProcessFieldParameters;
11
import org.gvsig.expressionevaluator.Expression;
12
import org.gvsig.expressionevaluator.ExpressionUtils;
13
import org.gvsig.expressionevaluator.MutableSymbolTable;
14
import org.gvsig.expressionevaluator.SymbolTable;
15
import org.gvsig.fmap.dal.DALLocator;
16
import org.gvsig.fmap.dal.DataManager;
17
import org.gvsig.fmap.dal.exception.DataException;
18
import org.gvsig.fmap.dal.expressionevaluator.FeatureSymbolTable;
19
import org.gvsig.fmap.dal.feature.EditableFeature;
20
import org.gvsig.fmap.dal.feature.Feature;
21
import org.gvsig.fmap.dal.feature.FeatureQuery;
22
import org.gvsig.fmap.dal.feature.FeatureReference;
23
import org.gvsig.fmap.dal.feature.FeatureSet;
24
import org.gvsig.fmap.dal.feature.FeatureStore;
25
import org.gvsig.tools.dataTypes.DataTypeUtils;
26
import org.gvsig.tools.task.SimpleTaskStatus;
27
import org.slf4j.Logger;
28
import org.slf4j.LoggerFactory;
29
import org.gvsig.fmap.dal.DataTransaction;
30
import org.gvsig.fmap.dal.feature.FeatureStoreNotification;
31
import org.gvsig.tools.ToolsLocator;
32
import org.gvsig.tools.dispose.DisposeUtils;
33
import org.gvsig.tools.identitymanagement.IdentityUtils;
34

    
35
/**
36
 *
37
 * @author jjdelcerro
38
 */
39
@SuppressWarnings("UseSpecificCatch")
40
public class UpdateTableProcessImpl implements UpdateTableProcess {
41

    
42
    protected final Logger LOGGER = LoggerFactory.getLogger(UpdateTableProcessImpl.class);
43

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

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

    
77
    @Override
78
    public void run() {
79
        try {
80
            DataManager dataManager = DALLocator.getDataManager();
81

    
82
            FeatureStore store = this.parameters.getStore();
83
            if( !IdentityUtils.isAuthorized(
84
                    "tools-updatetable", store, store.getFullName()) ) {
85
                this.status.message("User not authotized to this action");
86
                return;
87
            }
88
                    
89
            this.transaction = dataManager.createTransaction();
90
            this.transaction.begin();
91

    
92
            this.transaction.add(store, false);
93
            
94
            this.status.setTitle("Update table '" + store.getName() + "'");
95
            this.status.setIndeterminate();
96

    
97
            this.featureSymbolTable = dataManager.createFeatureSymbolTable();
98

    
99
            switch (this.parameters.getRowsToProcess()) {
100
                case UpdateTableProcessParameters.BATCHUPDATE_PROCESS_ALL:
101
                    update_all();
102
                    break;
103
                case UpdateTableProcessParameters.BATCHUPDATE_PROCESS_SELECTION:
104
                    update_selection();
105
                    break;
106
                case UpdateTableProcessParameters.BATCHUPDATE_PROCESS_EDITEDS:
107
                    update_editeds();
108
                    break;
109
            }
110
            if (this.status.isCancelled()) {
111
                abortEditing();
112
                DataTransaction.rollbackQuietly(this.transaction);
113
                this.status.message("Operation cancelled by user");
114
            } else {
115
                endEditing();
116
                this.transaction.commit();
117
                this.status.terminate();
118

    
119
                this.output();
120
                out.setVar("store", store);
121

    
122
                if (postprocess != null) {
123
                    postprocess.run();
124
                }
125
            }
126
            
127
        } catch (Exception ex) {
128
            DataTransaction.rollbackQuietly(this.transaction);
129
            this.status.abort();
130
            this.status.message("Can't update features");
131
                    
132
        } finally {
133
            DisposeUtils.dispose(this.transaction);
134
        }
135
    }
136

    
137
    public void update_editeds() throws DataException {
138
        Predicate<FeatureStoreNotification> saveNotificationsFilter = null;
139
        
140
        FeatureStore store = this.parameters.getStore();
141
        try {
142
            saveNotificationsFilter = store.setNotificationsFilter(new StoreNotificationsFilter());
143

    
144
            Expression filter = this.parameters.getFilter();
145
            List<FeatureReference> set = store.getEditedFeatures();
146
            if( set.isEmpty() ) {
147
                return;
148
            }
149
            this.beginEditing();
150
            long rows = set.size();
151
            this.status.setRangeOfValues(0, rows);
152

    
153
            for (FeatureReference featureReferfence : set) {
154
                this.status.incrementCurrentValue();
155
                if (this.status.isCancellationRequested()) {
156
                    this.status.cancel();
157
                    this.abortEditing();
158
                    return;
159
                }
160
                Feature feature = featureReferfence.getFeature();
161
                this.featureSymbolTable.setFeature(feature);
162
                boolean sholdProcessFeature = DataTypeUtils.toBoolean(filter.execute(featureSymbolTable), false);
163
                if (!sholdProcessFeature) {
164
                    continue;
165
                }
166

    
167
                EditableFeature editable_feature = feature.getEditable();
168
                process_feature(editable_feature);
169
                store.update(editable_feature);
170
                restart_editing();
171
            }
172
            this.endEditing();
173
        } finally {
174
            store.setNotificationsFilter(saveNotificationsFilter);
175
        }
176
    }
177

    
178
    public void update_selection() throws DataException {
179
        Predicate<FeatureStoreNotification> saveNotificationsFilter = null;
180

    
181
        FeatureStore store = this.parameters.getStore();
182
        try {
183
            saveNotificationsFilter = store.setNotificationsFilter(new StoreNotificationsFilter());
184
            
185
            Expression filter = this.parameters.getFilter();
186
            FeatureSet set = store.getFeatureSelection();
187
            this.beginEditing();
188
            long rows = set.getSize();
189
            this.status.setRangeOfValues(0, rows);
190

    
191
            for (Feature feature : set) {
192
                this.status.incrementCurrentValue();
193
                if (this.status.isCancellationRequested()) {
194
                    this.status.cancel();
195
                    this.abortEditing();
196
                    return;
197
                }
198

    
199
                this.featureSymbolTable.setFeature(feature);
200
                if( filter!=null ) {
201
                    boolean sholdProcessFeature = DataTypeUtils.toBoolean(filter.execute(featureSymbolTable), false);
202
                    if (!sholdProcessFeature) {
203
                        continue;
204
                    }
205
                }
206

    
207
                EditableFeature editable_feature = feature.getEditable();
208
                process_feature(editable_feature);
209
                set.update(editable_feature);
210
                restart_editing();
211
            }
212
            this.endEditing();
213
        } finally {
214
            store.setNotificationsFilter(saveNotificationsFilter);
215
        }
216
    }
217

    
218
    public void update_all() throws DataException {
219
        Predicate<FeatureStoreNotification> saveNotificationsFilter = null;
220
        
221
        FeatureStore store = this.parameters.getStore();
222
        try {
223
            saveNotificationsFilter = store.setNotificationsFilter(new StoreNotificationsFilter());
224

    
225
            Expression filter = this.parameters.getFilter();
226

    
227
            FeatureQuery query = store.createFeatureQuery(filter);
228
            FeatureSet set = store.getFeatureSet(query);
229
            this.transaction.add(set);
230

    
231
            this.beginEditing();
232
            long rows = set.getSize();
233
            this.status.setRangeOfValues(0, rows);
234

    
235
            for (Feature feature : set) {
236
                this.status.incrementCurrentValue();
237
                if (this.status.isCancellationRequested()) {
238
                    this.status.cancel();
239
                    this.abortEditing();
240
                    return;
241
                }
242
                EditableFeature editable_feature = feature.getEditable();
243
                process_feature(editable_feature);
244
                set.update(editable_feature);
245
                restart_editing();
246
            }
247
            this.endEditing();
248
        } finally {
249
            store.setNotificationsFilter(saveNotificationsFilter);
250
        }
251
        
252
    }
253

    
254
    private void process_feature(EditableFeature feature) {
255
        for (ProcessFieldParameters field : parameters) {
256
            if (!field.isUpdate()) {
257
                continue;
258
            }
259
            Expression expression = field.getExpression();
260
            if (expression == null || expression.isPhraseEmpty()) {
261
                continue;
262
            }
263
            this.featureSymbolTable.setFeature(feature);
264
            Object x = expression.execute(this.featureSymbolTable);
265
            feature.set(field.getName(), x);
266
        }
267
    }
268

    
269
    private void beginEditing() throws DataException {
270
        if( this.parameters.getRowsToProcess()==UpdateTableProcessParameters.BATCHUPDATE_PROCESS_EDITEDS ) {
271
            // Si hemos de procesar las editadas, mantenemos el modo de edicion
272
            // que hubiese, que deberia ser MODE_FULLEDIT.
273
            return;
274
        }
275
        if (!this.parameters.isBeginEditIfNeed()) {
276
            return;
277
        }
278
        FeatureStore store = this.parameters.getStore();
279
        if (store.getMode() != FeatureStore.MODE_QUERY) {
280
            if (this.parameters.isFinishAndRestarEdit()) {
281
                store.finishEditing();
282
            }
283
        }
284
        store.edit(this.parameters.getEditMode());
285
    }
286

    
287
    private void endEditing() throws DataException {
288
        if (this.parameters.isFinishEditAfterTerminate()) {
289
            FeatureStore store = this.parameters.getStore();
290
            if( store.getMode() != FeatureStore.MODE_QUERY ) {
291
                store.finishEditing();
292
            }
293
        }
294
    }
295

    
296
    private void abortEditing() throws DataException {
297
        if (this.parameters.isFinishEditAfterTerminate()) {
298
            FeatureStore store = this.parameters.getStore();
299
            if( store.getMode() != FeatureStore.MODE_QUERY ) {
300
                store.cancelEditing();
301
            }
302
        }
303
    }
304

    
305
    private void restart_editing() throws DataException {
306
        if( this.parameters.getRowsToProcess()==UpdateTableProcessParameters.BATCHUPDATE_PROCESS_EDITEDS ) {
307
            // Si estamos procesando las editadas no reiniciamos la edicion nunca
308
            // ya que perderiamos las features editadas.
309
            return;
310
        }
311
        int n = this.parameters.getFinishAndRestarEditEach();
312
        if (n < 1) {
313
            return;
314
        }
315
        FeatureStore store = this.parameters.getStore();
316
        switch (store.getMode()) {
317
            case FeatureStore.MODE_PASS_THROUGH:
318
            case FeatureStore.MODE_APPEND:
319
                return;
320
            case FeatureStore.MODE_FULLEDIT:
321
            default:
322
                break;
323
        }
324
        if (store.getMode() != FeatureStore.MODE_FULLEDIT) {
325
            return;
326
        }
327
        if (store.getPendingChangesCount() < n) {
328
            return;
329
        }
330
        store.finishEditing();
331
        store.edit(this.parameters.getEditMode());
332
    }
333

    
334
    @Override
335
    public UpdateTableProcess parameters(UpdateTableProcessParameters params) {
336
        this.parameters = params;
337
        return this;
338
    }
339

    
340
    @Override
341
    public UpdateTableProcess status(SimpleTaskStatus taskStatus) {
342
        this.status = taskStatus;
343
        return this;
344
    }
345

    
346
    @Override
347
    public UpdateTableProcess postProcess(Runnable postProcess) {
348
        this.postprocess = postProcess;
349
        return this;
350
    }
351

    
352
    @Override
353
    public UpdateTableProcessParameters createParameters() {
354
        return new UpdateTableProcessParametersImpl();
355
    }
356

    
357
    @Override
358
    public SymbolTable output() {
359
        if( this.out == null ) {
360
            this.out = ExpressionUtils.createSymbolTable();
361
        }
362
        return this.out;
363
    }
364
    
365
    private class StoreNotificationsFilter implements Predicate<FeatureStoreNotification> {
366

    
367
        @Override
368
        public boolean test(FeatureStoreNotification t) {
369
            if( t!=null ) {
370
                switch(t.getType()) {
371
                    case FeatureStoreNotification.AFTER_UPDATE:
372
                    case FeatureStoreNotification.BEFORE_UPDATE:
373
                        return true;
374
                }
375
                LOGGER.info(t.getType());
376
            }
377
            return false;
378
        }
379
        
380
    }
381
    
382

    
383
}