Statistics
| Revision:

gvsig-projects-pool / org.gvsig.vcsgis / trunk / org.gvsig.vcsgis / org.gvsig.vcsgis.lib / org.gvsig.vcsgis.lib.impl / src / main / java / org / gvsig / vcsgis / lib / workspace / tables / WorkspaceChangesTable.java @ 3633

History | View | Annotate | Download (29.9 KB)

1
package org.gvsig.vcsgis.lib.workspace.tables;
2

    
3
import java.sql.Connection;
4
import java.sql.ResultSet;
5
import java.sql.SQLException;
6
import java.util.Iterator;
7
import java.util.List;
8
import javax.json.JsonObject;
9
import org.apache.commons.collections.CollectionUtils;
10
import org.apache.commons.lang3.StringUtils;
11
import org.gvsig.expressionevaluator.ExpressionBuilder;
12
import org.gvsig.expressionevaluator.ExpressionEvaluatorLocator;
13
import org.gvsig.expressionevaluator.ExpressionEvaluatorManager;
14
import org.gvsig.expressionevaluator.ExpressionUtils;
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.feature.EditableFeature;
19
import org.gvsig.fmap.dal.feature.EditableFeatureType;
20
import org.gvsig.fmap.dal.feature.Feature;
21
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
22
import org.gvsig.fmap.dal.feature.FeatureQuery;
23
import org.gvsig.fmap.dal.feature.FeatureSet;
24
import org.gvsig.fmap.dal.feature.FeatureSet.DisposableFeatureSetIterable;
25
import org.gvsig.fmap.dal.feature.FeatureStore;
26
import static org.gvsig.fmap.dal.feature.FeatureStore.MODE_PASS_THROUGH;
27
import org.gvsig.fmap.dal.feature.FeatureType;
28
import org.gvsig.json.Json;
29
import org.gvsig.tools.dataTypes.DataTypes;
30
import org.gvsig.tools.dispose.DisposableIterable;
31
import org.gvsig.tools.dispose.DisposeUtils;
32
import org.gvsig.tools.dynobject.DynObjectValueItem;
33
import org.gvsig.tools.util.GetItemWithSize64;
34
import org.gvsig.tools.util.GetItemWithSizeAndIterator64;
35
import org.gvsig.vcsgis.lib.VCSGisEntity;
36
import org.gvsig.vcsgis.lib.VCSGisManager;
37
import static org.gvsig.vcsgis.lib.VCSGisManager.OP_ADD_ENTITY;
38
import static org.gvsig.vcsgis.lib.VCSGisManager.OP_DELETE;
39
import static org.gvsig.vcsgis.lib.VCSGisManager.OP_INSERT;
40
import static org.gvsig.vcsgis.lib.VCSGisManager.OP_UPDATE;
41
import static org.gvsig.vcsgis.lib.VCSGisManager.STATE_CONFLICT;
42
import static org.gvsig.vcsgis.lib.VCSGisManager.STATE_LOCAL_MODIFIED;
43
import static org.gvsig.vcsgis.lib.VCSGisManager.STATE_LOCAL_NEW;
44
import static org.gvsig.vcsgis.lib.VCSGisManager.STATE_LOCAL_UNMODIFIED;
45
import static org.gvsig.vcsgis.lib.VCSGisManager.VCSGISCODELEN;
46
import org.gvsig.vcsgis.lib.VCSGisRuntimeException;
47
import org.gvsig.vcsgis.lib.VCSGisUtils;
48
import org.gvsig.vcsgis.lib.workspace.VCSGisWorkspace;
49
import org.gvsig.vcsgis.lib.workspace.VCSGisWorkspaceChange;
50
import org.gvsig.vcsgis.lib.workspace.VCSGisWorkspaceEntity;
51
import org.gvsig.vcsgis.lib.workspace.tables.AbstractTable.AbstractRow;
52
import org.gvsig.vcsgis.lib.workspace.tables.RemoteChangesTable.RemoteChangeRow;
53

    
54
/**
55
 *
56
 * @author gvSIG Team
57
 */
58
@SuppressWarnings("UseSpecificCatch")
59
public class WorkspaceChangesTable extends AbstractTable {
60

    
61
    
62
    public static final String TABLE_NAME = "VCSGIS_WSCHANGES";
63
    
64
    public static final String COD_CHANGE = "COD_WSCHANGE";
65
    public static final String COD_ENTITY = "COD_ENTITY";
66
    public static final String SELECTED = "WSCH_SELECTED";
67
    public static final String FEATUREID = "WSCH_FEATURECODE";
68
    public static final String OPERATION = "WSCH_OPERATION";
69
    public static final String STATUS = "WSCH_STATUS";
70
    private static final String FEATURE_DATA = "WSCH_DATA";
71

    
72
    private static final String LABEL = "WSCH_LABEL";
73
    private static final int MAX_SIZE_LABEL = 40;
74

    
75
    @SuppressWarnings("UseSpecificCatch")
76
    public static class WorkspaceChangeRow extends AbstractRow implements VCSGisWorkspaceChange {
77

    
78
        protected VCSGisWorkspaceEntity entity;
79
        
80
        public WorkspaceChangeRow(VCSGisWorkspace workspace) {
81
            this(workspace, null);
82
            setStatus(STATE_LOCAL_UNMODIFIED);
83
        }
84
        
85
        public WorkspaceChangeRow(VCSGisWorkspace workspace, Feature feature) {
86
            super(workspace, TABLE_NAME, COD_CHANGE, feature);
87
        }
88
        
89
        @Override
90
        public String getEntityCode() {
91
            return this.getString(COD_ENTITY);
92
        }
93

    
94
        @Override
95
        public String getRelatedFeatureCode() {
96
            return this.getString(FEATUREID);
97
        }
98
        
99
        @Override
100
        public int getOperation() {
101
            return this.getInt(OPERATION);
102
        }
103
        
104
        @Override
105
        public String getOperationLabel() {
106
            return this.getLabelOfValue(OPERATION);
107
        }
108
        
109
        @Override
110
        public String getLabel() {
111
            return this.getString(LABEL);
112
        }
113

    
114
        @Override
115
        public boolean isSelected() {
116
            return this.getBoolean(SELECTED);
117
        }
118
        
119
        public void setEntityCode(String code) {
120
            this.set(COD_ENTITY, code);
121
        }
122

    
123
        public void setFeatureCode(String code) {
124
            this.set(FEATUREID, code);
125
        }
126
        
127
        public void setOperation(int op) {
128
            this.set(OPERATION, op);
129
        }
130
        
131
        public void setStatus(int status) {
132
            this.set(STATUS, status);
133
        }
134
        
135
        @Override
136
        public void setSelected(boolean selected) {
137
            this.set(SELECTED, selected);
138
        }
139

    
140
        public void setLabel(String label) {
141
            this.set(LABEL, StringUtils.abbreviate(label, MAX_SIZE_LABEL));
142
        }
143
        
144
        @Override
145
        public String getRelatedFeatureData() {
146
            String entityName = "unknown";
147
            String code = "unknown";
148
            try {
149
                entityName = this.getEntity().getEntityName();
150
                code = this.getRelatedFeatureCode();
151
                FeatureStore store = workspace.getFeatureStore(entityName);
152
                Feature f = store.findFirst("\""+this.getEntity().getFeatureIdFieldName()+"\"='"+code+"'");
153
                if( f==null ) {
154
                    return ""; //null;
155
//                    throw new RuntimeException("Feature '"+entityName+"/"+code+"'not found.");
156
                }
157
                return f.toJson().toString();
158
            } catch (Exception ex) {
159
                throw new RuntimeException("Can't retrieve feature '"+entityName+"/"+code+"'.",ex);
160
            }
161
        }    
162

    
163
        @Override
164
        public JsonObject getRelatedFeatureDataAsJson() {
165
            String s = this.getRelatedFeatureData();
166
            return Json.createObject(s);
167
        }
168
        
169
        @Override
170
        public String toString() {
171
            switch (this.getOperation()) {
172
                case OP_ADD_ENTITY:
173
                    return "{ OP:'ADD_ENTITY', ENTITYCODE:'"+this.getEntityCode()+"', }";
174
                case OP_INSERT:
175
                    return "{ OP:'INSERT', ENTITYCODE:'"+this.getEntityCode()+"', FEATURECODE:'"+this.getRelatedFeatureCode()+"', DATA:'"+this.getRelatedFeatureData()+"' }";
176
                case OP_UPDATE:
177
                    return "{ OP:'UPDATE', ENTITYCODE:'"+this.getEntityCode()+"', FEATURECODE:'"+this.getRelatedFeatureCode()+"', DATA:'"+this.getRelatedFeatureData()+"' }";
178
                case OP_DELETE:
179
                    return "{ OP:'DELETE', ENTITYCODE:'"+this.getEntityCode()+"', FEATURECODE:'"+this.getRelatedFeatureCode()+"' }";
180
                default:
181
                    return "{ OP:'"+this.getOperation()+"', ENTITYCODE:'"+this.getEntityCode()+"', FEATURECODE:'"+this.getRelatedFeatureCode()+"' }";
182
            }
183
        }
184
        
185
        @Override
186
        public Feature getRelatedFeature() {
187
            Feature f = this.workspace.getRelatedFeature(this.getEntity(), this.getRelatedFeatureCode());
188
            if (f == null) {
189
                throw new RuntimeException("Feature '" + this.getEntity().getEntityName() + "/" + this.getRelatedFeatureCode() + "'not found.");
190
            }
191
            return f;
192
        }        
193

    
194
        public VCSGisWorkspaceEntity getEntity() {
195
            if( this.entity == null ) {
196
                this.entity = this.workspace.getWorkspaceEntityByCode(this.getEntityCode());
197
            }
198
            return this.entity;
199
        }
200

    
201
        @Override
202
        public int getStatus() {
203
            return this.getInt(STATUS);
204
        }
205

    
206
        @Override
207
        public void update(FeatureStore store) {
208
            this.updateStatus();
209
            super.update(store);
210
        }
211

    
212
        @Override
213
        public void insert(FeatureStore store) {
214
            this.updateStatus();
215
            super.insert(store);
216
        }
217
        
218
        private void updateStatus() {
219
            if(getStatus() == STATE_LOCAL_UNMODIFIED){
220
                switch(this.getOperation()){
221
                    case OP_INSERT:
222
                    case OP_ADD_ENTITY:
223
                        setStatus(STATE_LOCAL_NEW);
224
                        return;
225
                    case OP_DELETE:
226
                    case OP_UPDATE:
227
                        setStatus(STATE_LOCAL_MODIFIED);
228
                        return;
229
                }
230
            }
231
        }
232
        
233
        public void revert(FeatureStore userStore, FeatureStore changesStore) throws DataException {
234
            String code = this.getRelatedFeatureCode();
235
            EditableFeature editable;
236
            switch (this.getOperation()) {
237
                case OP_INSERT:
238
                    userStore.delete("\""+VCSGisManager.FEATURECODE_FIELD_NAME+"\" = '"+code+"'");
239
                    changesStore.delete("\""+COD_CHANGE+"\" = '"+this.getCode()+"'");
240
                    break;
241
                case OP_ADD_ENTITY:
242
                    break;
243
                case OP_UPDATE:
244
                    Feature feat = userStore.findFirst("\""+VCSGisManager.FEATURECODE_FIELD_NAME+"\" = '"+code+"'");
245
                    if(feat == null) {
246
                        throw new VCSGisRuntimeException(1, "xxx");
247
                    }
248
                    editable = feat.getEditable();
249
                    editable.copyFrom(this.getDataAsJson());
250
                    userStore.update(editable);
251
                    changesStore.delete("\""+COD_CHANGE+"\" = '"+this.getCode()+"'");
252
                    break;
253
                case OP_DELETE:
254
                    editable = userStore.createNewFeature(this.getDataAsJson());
255
                    userStore.insert(editable);
256
                    changesStore.delete("\""+COD_CHANGE+"\" = '"+this.getCode()+"'");
257
                    break;
258
            }
259
        }
260

    
261
        public void setData(String data) {
262
            this.set(FEATURE_DATA, data);
263
        }
264

    
265
        @Override
266
        public String getData() {
267
            return this.getString(FEATURE_DATA);
268
        }
269

    
270
        @Override
271
        public JsonObject getDataAsJson() {
272
            String s = this.getData();
273
            return Json.createObject(s);
274
        }
275
        
276
        
277

    
278
    }
279
    
280
    public WorkspaceChangesTable() {
281
        super(TABLE_NAME, featureType());
282
    }
283

    
284
    public DisposableFeatureSetIterable getByOperation(VCSGisWorkspace workspace, int op) {
285
        return getByOperation(workspace, null, op);
286
//        FeatureStore store = null;
287
//        try {
288
//            store = workspace.getFeatureStore(TABLE_NAME);
289
//            FeatureQuery query = store.createFeatureQuery();
290
//            query.addFilter("\""+WorkspaceChangesTable.OPERATION+"\"="+op);
291
//            query.retrievesAllAttributes();
292
//            DisposableFeatureSetIterable changes = store.getFeatureSet(query).iterable();
293
//            return changes;
294
//        } catch (Exception ex) {
295
//            throw new RuntimeException("Can't retrieve changes for operartion "+op+".", ex);
296
//        } finally {
297
//            if( store!=null ) {
298
//                DisposeUtils.dispose(store);
299
//            }
300
//        }
301
    }
302

    
303
    public DisposableFeatureSetIterable getByOperation(VCSGisWorkspace workspace, String entityCode, int op) {
304
        FeatureStore store = null;
305
        try {
306
            store = workspace.getFeatureStore(TABLE_NAME);
307
            FeatureQuery query = store.createFeatureQuery();
308
            if( !StringUtils.isBlank(entityCode) ) {
309
                query.addFilter("\""+COD_ENTITY+"\" ='"+entityCode+"' AND \""+WorkspaceChangesTable.OPERATION+"\"="+op);
310
            } else {
311
                query.addFilter("\""+WorkspaceChangesTable.OPERATION+"\"="+op);
312
            }
313
            
314
            query.retrievesAllAttributes();
315
            DisposableFeatureSetIterable changes = store.getFeatureSet(query).iterable();
316
            return changes;
317
        } catch (Exception ex) {
318
            throw new RuntimeException("Can't retrieve changes for operartion "+op+".", ex);
319
        } finally {
320
            if( store!=null ) {
321
                DisposeUtils.dispose(store);
322
            }
323
        }
324
    }
325
    
326
    
327
    public DisposableFeatureSetIterable getGroupedByEntity(VCSGisWorkspace workspace) {
328
        FeatureStore store = null;
329
        try {
330
            store = workspace.getFeatureStore(TABLE_NAME);
331
            FeatureQuery query = store.createFeatureQuery();
332

    
333
            query.getOrder().add(WorkspaceChangesTable.COD_ENTITY,true);
334
            query.getGroupByColumns().add(WorkspaceChangesTable.COD_ENTITY);
335
            query.getAggregateFunctions().put(SELECTED, "MAX");
336
            query.retrievesAllAttributes();
337
            DisposableFeatureSetIterable changes = store.getFeatureSet(query).iterable();
338
            return changes;
339
        } catch (Exception ex) {
340
            throw new RuntimeException("Can't retrieve changes grouped by entity.", ex);
341
        } finally {
342
            if( store!=null ) {
343
                DisposeUtils.dispose(store);
344
            }
345
        }
346
    }
347

    
348
    public DisposableFeatureSetIterable getSelectedsWithoutAddEntity(VCSGisWorkspace workspace) {
349
        return getSelectedsWithoutAddEntity(workspace, null);
350
//        FeatureStore store = null;
351
//        try {
352
//            store = workspace.getFeatureStore(TABLE_NAME);
353
//            FeatureQuery query = store.createFeatureQuery();
354
//
355
//            //FIXME: No enviar al servidor cambios repetidos sobre la misma feature
356
//            query.setFilter("\""+SELECTED+"\" AND \""+OPERATION+"\" <> "+OP_ADD_ENTITY);
357
//            query.retrievesAllAttributes();
358
//            DisposableFeatureSetIterable changes = store.getFeatureSet(query).iterable();
359
//            if( changes.isEmpty() ) {
360
//                DisposeUtils.disposeQuietly(changes);
361
//                return null;
362
//            }
363
//            return changes;
364
//        } catch (Exception ex) {
365
//            throw new RuntimeException("Can't retrieve all changes.", ex);
366
//        } finally {
367
//            if( store!=null ) {
368
//                DisposeUtils.dispose(store);
369
//            }
370
//        }
371
    }
372
    
373
    public DisposableFeatureSetIterable getSelectedsWithoutAddEntity(VCSGisWorkspace workspace, List<String> entityCodes) {
374
        FeatureStore store = null;
375
        try {
376
            store = workspace.getFeatureStore(TABLE_NAME);
377
            FeatureQuery query = store.createFeatureQuery();
378

    
379
            if(CollectionUtils.isEmpty(entityCodes)){
380
                query.setFilter("\""+SELECTED+"\" AND \""+OPERATION+"\" <> "+OP_ADD_ENTITY);
381
            } else {
382
                ExpressionBuilder expBuilder = ExpressionUtils.createExpressionBuilder();
383
                for (String entityCode : entityCodes) {
384
                    expBuilder.or(expBuilder.eq(expBuilder.column(COD_ENTITY), expBuilder.constant(entityCode)));
385
                }
386
                expBuilder.and(expBuilder.column(SELECTED)).and(expBuilder.ne(expBuilder.column(OPERATION), expBuilder.constant(OP_ADD_ENTITY)));
387
                query.setFilter(expBuilder.value().toString());
388
            }
389
            
390
            query.retrievesAllAttributes();
391
            DisposableFeatureSetIterable changes = store.getFeatureSet(query).iterable();
392
            if( changes.isEmpty() ) {
393
                DisposeUtils.disposeQuietly(changes);
394
                return null;
395
            }
396
            return changes;
397
        } catch (Exception ex) {
398
            throw new RuntimeException("Can't retrieve all changes.", ex);
399
        } finally {
400
            if( store!=null ) {
401
                DisposeUtils.dispose(store);
402
            }
403
        }
404
    }
405
    
406
    public DisposableFeatureSetIterable getAll(VCSGisWorkspace workspace) {
407
        FeatureStore store = null;
408
        try {
409
            store = workspace.getFeatureStore(TABLE_NAME);
410
            DisposableFeatureSetIterable changes = store.getFeatureSet().iterable();
411
            return changes;
412
        } catch (Exception ex) {
413
            throw new RuntimeException("Can't retrieve all changes.", ex);
414
        } finally {
415
            if( store!=null ) {
416
                DisposeUtils.dispose(store);
417
            }
418
        }
419
    }
420

    
421
    public GetItemWithSize64<Feature> getByEntityCode(VCSGisWorkspace workspace, List<VCSGisEntity> entities) {
422
        FeatureStore store = null;
423
        try {
424
            store = workspace.getFeatureStore(TABLE_NAME);
425
            if( CollectionUtils.isEmpty(entities) ) {
426
                GetItemWithSizeAndIterator64<Feature> changes = store.getFeatures64(
427
                        null, 
428
                        "\""+COD_ENTITY+"\",-\""+OPERATION+"\",\""+COD_CHANGE+"\"", 
429
                        true);
430
                return changes;
431
            }
432
            ExpressionBuilder exprBuilder = ExpressionUtils.createExpressionBuilder();
433
            for (VCSGisEntity entity : entities) {
434
                exprBuilder.or(exprBuilder.eq(exprBuilder.column(COD_ENTITY), exprBuilder.constant(entity.getEntityCode())));
435
            }
436
            GetItemWithSizeAndIterator64<Feature> changes = store.getFeatures64(
437
                    exprBuilder.value().toString(),
438
                    "\""+COD_ENTITY+"\",-\""+OPERATION+"\",\""+COD_CHANGE+"\"", 
439
                    true
440
            );
441
            return changes;
442
        } catch (Exception ex) {
443
            throw new RuntimeException("Can't retrieve changes by entity.", ex);
444
        } finally {
445
            if( store!=null ) {
446
                DisposeUtils.dispose(store);
447
            }
448
        }
449
    }
450
    
451
    public long getCountLocalChangesOfEntity(VCSGisWorkspace workspace, String entityCode) {
452
        FeatureStore store = null;
453
        FeatureSet changes = null;
454
        try {
455
            store = workspace.getFeatureStore(TABLE_NAME);
456
            if( StringUtils.isBlank(entityCode) ) {
457
                throw new IllegalArgumentException("entityCode is required.");
458
            }
459
            changes = store.getFeatureSet(
460
                    "\""+COD_ENTITY+"\"='"+entityCode+"'"
461
            );
462
            return changes.size64();
463
        } catch (Exception ex) {
464
            throw new RuntimeException("Can't retrieve changes by entity.", ex);
465
        } finally {
466
            DisposeUtils.disposeQuietly(changes);
467
            DisposeUtils.disposeQuietly(store);
468
        }
469
    }
470

    
471
    public WorkspaceChangeRow getByEntityAndDataCode(
472
            VCSGisWorkspace workspace, 
473
            String entityCode, 
474
            String featureCode,
475
            FeatureStore localChangesStore
476
        ) {
477
        FeatureStore store = localChangesStore;
478
        try {
479
            if(store == null){
480
                store = workspace.getFeatureStore(TABLE_NAME);
481
            }
482
            Feature f = store.findFirst(
483
                    "\"" + COD_ENTITY + "\"='" + entityCode + "' AND \""+FEATUREID+"\"='"+featureCode+"'"
484
            );
485
            if (f == null) {
486
                return null;
487
            }
488
            WorkspaceChangeRow row = new WorkspaceChangeRow(workspace, f);
489
            return row;
490
        } catch (Exception ex) {
491
            throw new RuntimeException("Can't retrieve change for 'FEATURECODE[" + featureCode + "]'.", ex);
492
        } finally {
493
            if(localChangesStore == null){
494
                DisposeUtils.disposeQuietly(store);
495
            }
496
        }
497
    }
498

    
499
    public void deleteAll(VCSGisWorkspace workspace) {
500
        FeatureStore store = null;
501
        try {
502
            store = workspace.openFeatureStore(TABLE_NAME);
503
            store.edit(MODE_PASS_THROUGH);
504
            store.delete("TRUE");
505
            store.finishEditing();
506
        } catch (Exception ex) {
507
            FeatureStore.cancelEditingQuietly(store);
508
            throw new RuntimeException("Can't delete all changes.", ex);
509
        } finally {
510
            if( store!=null ) {
511
                DisposeUtils.dispose(store);
512
            }
513
        }
514
    }
515

    
516
    public void deleteSelecteds(VCSGisWorkspace workspace, List<String> entityCodes) {
517
        FeatureStore store = null;
518
        try {
519
            store = workspace.openFeatureStore(TABLE_NAME);
520
            store.edit(MODE_PASS_THROUGH);
521
            ExpressionBuilder expBuilder = ExpressionUtils.createExpressionBuilder();
522
            if(CollectionUtils.isNotEmpty(entityCodes)){
523
                for (String entityCode : entityCodes) {
524
                    expBuilder.or(expBuilder.eq(expBuilder.column(COD_ENTITY), expBuilder.constant(entityCode)));
525
                }
526
            }
527
            expBuilder.and(expBuilder.column(SELECTED));
528
            
529
            store.delete(expBuilder.value().toString());
530
            store.finishEditing();
531
        } catch (Exception ex) {
532
            FeatureStore.cancelEditingQuietly(store);
533
            throw new RuntimeException("Can't delete selected changes.", ex);
534
        } finally {
535
            if( store!=null ) {
536
                DisposeUtils.dispose(store);
537
            }
538
        }
539
    }
540

    
541
    public void deleteByEntity(VCSGisWorkspace workspace, String entityCode) {
542
        FeatureStore store = null;
543
        try {
544
            store = workspace.openFeatureStore(TABLE_NAME);
545
            store.edit(MODE_PASS_THROUGH);
546
            store.delete("\""+COD_ENTITY+"\"='"+entityCode+"'");
547
            store.finishEditing();
548
        } catch (Exception ex) {
549
            FeatureStore.cancelEditingQuietly(store);
550
            throw new RuntimeException("Can't delete selected changes.", ex);
551
        } finally {
552
            if( store!=null ) {
553
                DisposeUtils.dispose(store);
554
            }
555
        }
556
    }
557
    
558
        public DisposableFeatureSetIterable getSelectedsByEntityCodeAsIterator(VCSGisWorkspace workspace, String entityCode) {
559
        FeatureStore store = null;
560
        try {
561
            store = workspace.getFeatureStore(TABLE_NAME);
562
            FeatureSet changes;
563
            if( StringUtils.isBlank(entityCode) ) {
564
                changes = store.getFeatureSet("\""+SELECTED+"\"");
565
            } else {
566
                changes = store.getFeatureSet("\""+SELECTED+"\" AND \""+COD_ENTITY+"\"='"+entityCode+"'");
567
            }
568
            return changes.iterable();
569
        } catch (Exception ex) {
570
            throw new RuntimeException("Can't retrieve selected remote changes by entity code (ENTITY["+entityCode+"]).", ex);
571
        } finally {
572
            if( store!=null ) {
573
                DisposeUtils.dispose(store);
574
            }
575
        }
576
    }
577

    
578

    
579
    public void deleteSelectedsByEntity(VCSGisWorkspace workspace, String entityCode) {
580
        FeatureStore store = null;
581
        try {
582
            store = workspace.openFeatureStore(TABLE_NAME);
583
            store.edit(MODE_PASS_THROUGH);
584
            store.delete("\""+COD_ENTITY+"\"='"+entityCode+"'"+" AND "+"\""+SELECTED+"\"");
585
            store.finishEditing();
586
        } catch (Exception ex) {
587
            FeatureStore.cancelEditingQuietly(store);
588
            throw new RuntimeException("Can't delete selected changes.", ex);
589
        } finally {
590
            if( store!=null ) {
591
                DisposeUtils.dispose(store);
592
            }
593
        }
594
    }
595

    
596
    public WorkspaceChangeRow find(VCSGisWorkspace workspace, FeatureStore store, String entityCode, String featureCode) {
597
        try {
598
            Feature f = store.findFirst(
599
                    "\""+FEATUREID+"\"='"+featureCode+"'"
600
//                    "\""+COD_ENTITY+"\"='"+entityCode+"' AND \""+FEATUREID+"\"='"+featureCode+"'"
601
            );
602
            if(f==null){
603
                return null;
604
            }
605
            return new WorkspaceChangeRow(workspace, f);
606
        } catch (Exception ex) {
607
            throw new RuntimeException("Can't retrieve change.", ex);
608
        }
609
    }
610
    
611
    public static final FeatureType featureType() {
612
        DataManager dataManager = DALLocator.getDataManager();
613
        EditableFeatureType ft = dataManager.createFeatureType();
614
        ft.setLabel("VCSGIS Local changes");
615
        ft.getTags().set("ID", TABLE_NAME);
616
        ft.add(COD_CHANGE, DataTypes.STRING)
617
                .setSize(VCSGISCODELEN)
618
                .setIsPrimaryKey(true)
619
                .setLabel("Code")
620
                .setReadOnly(false);        
621
        ft.add(COD_ENTITY, DataTypes.STRING)
622
//                .setIsIndexed(true)
623
                .setAllowIndexDuplicateds(true)
624
                .setSize(VCSGISCODELEN)
625
                .setLabel("Entity code");
626
        ft.add(SELECTED, DataTypes.BOOLEAN)
627
//                .setIsIndexed(true)
628
                .setAllowIndexDuplicateds(true)
629
                .setLabel("Selected");
630
        ft.add(FEATUREID, DataTypes.STRING)
631
                .setIsIndexed(true)
632
                .setSize(VCSGISCODELEN)
633
                .setLabel("Identifier")
634
                .setDescription("The identifier of the feature");
635
        ft.add(OPERATION, DataTypes.INTEGER)
636
                .setIsIndexed(true)
637
                .setLabel("Operation")
638
                .setAvailableValues(new DynObjectValueItem[] {
639
                    new DynObjectValueItem(OP_ADD_ENTITY, "Add entity"),
640
                    new DynObjectValueItem(OP_INSERT, "Insert"),
641
                    new DynObjectValueItem(OP_UPDATE, "Update"),
642
                    new DynObjectValueItem(OP_DELETE, "Delete")
643
                });
644
        ft.add(STATUS, DataTypes.INTEGER)
645
                .setLabel("Status")
646
                .setAvailableValues(new DynObjectValueItem[] {
647
                    new DynObjectValueItem(STATE_LOCAL_UNMODIFIED, "Unmodified"),
648
                    new DynObjectValueItem(STATE_LOCAL_MODIFIED, "Modified"),
649
                    new DynObjectValueItem(STATE_CONFLICT, "Conflict")
650
                });
651
        ft.add(LABEL, DataTypes.STRING)
652
                .setIsIndexed(false)
653
                .setSize(MAX_SIZE_LABEL)
654
                .setLabel("Label")
655
                .setDescription("The label of the feature");
656
        ft.add(FEATURE_DATA, DataTypes.STRING)
657
                .setLabel("Data");
658
        
659
        return ft.getNotEditableCopy();
660
    }
661
    
662
    public void removeLocalChangesRelatedToSelectedRemoteChanges(VCSGisWorkspace workspace, VCSGisEntity lentity) {
663
        String sql = String.format(VCSGisUtils.getSqlTemplate(workspace.getExplorer().getProviderName(), "removeLocalChangesRelatedToSelectedRemoteChanges"), lentity.getEntityCode());
664
        Object res = workspace.getExplorer().execute(sql);
665
    }
666

    
667
    public DisposableIterable<WorkspaceChangeRow> getChangesWidthUserData(VCSGisWorkspace workspace, VCSGisEntity lentity, RemoteChangeRow remoteChange, FeatureStore localChangesStore) {
668

    
669
        FeatureType featType = lentity.getFeatureType();
670
        JsonObject data = remoteChange.getRelatedFeatureDataAsJson();
671
        ExpressionEvaluatorManager expManager = ExpressionEvaluatorLocator.getManager();
672
        ExpressionBuilder builder = expManager.createExpressionBuilder();
673
        builder.set(null);
674
        for (FeatureAttributeDescriptor attr : featType) {
675
            if(StringUtils.equalsAnyIgnoreCase(lentity.getFeatureIdFieldName(),attr.getName())){
676
                continue;
677
            }
678
            if(attr.isIndexed() && !attr.allowIndexDuplicateds()){
679
                Object value = Json.toObject(data, attr.getName());
680
                builder.or(
681
                    builder.eq(
682
                        builder.column(attr.getName()), 
683
                        builder.constant(value)
684
                    )
685
                );
686
            }
687
        }
688
        ExpressionBuilder.Value value = builder.value();
689
        if(value == null){
690
            return null;
691
        }
692
        
693
        String sql = String.format(
694
                VCSGisUtils.getSqlTemplate(
695
                        workspace.getExplorer().getProviderName(), 
696
                        "getChangesWidthUserData"
697
                ), 
698
                lentity.getEntityName(),
699
                lentity.getFeatureIdFieldName(),
700
                remoteChange.getRelatedFeatureCode(),
701
                builder.toString()
702
                );
703

    
704
        final ResultSet rs = (ResultSet) workspace.getExplorer().execute(sql);
705
        if(rs == null){
706
            return null;
707
        }
708
        final WorkspaceChangeRow row;
709
        try {
710
            row = new WorkspaceChangeRow(workspace, localChangesStore.createNewFeature());
711
        } catch (DataException ex) {
712
            try {
713
                rs.close();
714
            } catch (SQLException ex2) {
715
            }
716
            return null;
717
        }
718
        DisposableIterable<WorkspaceChangeRow> r = new DisposableIterable<WorkspaceChangeRow>() {
719
            @Override
720
            public Iterator<WorkspaceChangeRow> iterator() {
721
                Iterator<WorkspaceChangeRow> it = new Iterator<WorkspaceChangeRow>() {
722
                    @Override
723
                    public boolean hasNext() {
724
                        try {
725
                            return rs.next();
726
                        } catch (SQLException ex) {
727
                            return false;
728
                        }
729
                    }
730

    
731
                    @Override
732
                    public WorkspaceChangeRow next() {
733
                        try {
734
                            row.setCode(rs.getString(COD_CHANGE));
735
                            row.setEntityCode(rs.getString(COD_ENTITY));
736
                            row.setFeatureCode(rs.getString(FEATUREID));
737
                            row.setLabel(rs.getString(LABEL));
738
                            row.setOperation(rs.getInt(OPERATION));
739
                            row.setSelected(rs.getBoolean(SELECTED));
740
                            row.setStatus(rs.getInt(STATUS));
741
                            return row;
742
                        } catch (SQLException ex) {
743
                            return null;
744
                        }
745
                    }
746
                };
747
                return it;
748
            }
749

    
750
            @Override
751
            public void dispose() {
752
                try {
753
                    Connection conn = rs.getStatement().getConnection();
754
                    rs.close();
755
                    conn.close();
756
                } catch (SQLException ex) {
757
                    LOGGER.warn("Can't close resultSet.", ex);
758
                }
759
            }
760
        };
761
        
762
        return r;
763
    }
764
    
765
}