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 |
} |