gvsig-projects-pool / org.gvsig.online / trunk / org.gvsig.online / org.gvsig.online.lib / org.gvsig.online.lib.impl / src / main / java / org / gvsig / online / lib / impl / workspace / tables / WorkspaceChangesTable.java @ 9512
History | View | Annotate | Download (36.5 KB)
1 |
package org.gvsig.online.lib.impl.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 static org.gvsig.fmap.dal.DataManager.RECOMENDED_SIZE_FOR_CLOB; |
18 |
import org.gvsig.fmap.dal.DataTransaction; |
19 |
import org.gvsig.fmap.dal.exception.DataException; |
20 |
import org.gvsig.fmap.dal.feature.DisposableFeatureSetIterable; |
21 |
import org.gvsig.fmap.dal.feature.EditableFeature; |
22 |
import org.gvsig.fmap.dal.feature.EditableFeatureType; |
23 |
import org.gvsig.fmap.dal.feature.Feature; |
24 |
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor; |
25 |
import org.gvsig.fmap.dal.feature.FeatureQuery; |
26 |
import org.gvsig.fmap.dal.feature.FeatureSet; |
27 |
import org.gvsig.fmap.dal.feature.FeatureStore; |
28 |
import static org.gvsig.fmap.dal.feature.FeatureStore.MODE_PASS_THROUGH; |
29 |
import org.gvsig.fmap.dal.feature.FeatureType; |
30 |
import org.gvsig.fmap.dal.store.jdbc2.JDBCServerExplorer; |
31 |
import org.gvsig.json.Json; |
32 |
import org.gvsig.online.lib.api.workingcopy.OnlineEntity; |
33 |
import org.gvsig.online.lib.api.OnlineManager; |
34 |
import static org.gvsig.online.lib.api.OnlineManager.FEATURECODE_FIELD_NAME; |
35 |
import static org.gvsig.online.lib.api.OnlineManager.ONLINECODELEN; |
36 |
import static org.gvsig.online.lib.api.OnlineManager.OP_DELETE; |
37 |
import static org.gvsig.online.lib.api.OnlineManager.OP_IGNORE; |
38 |
import static org.gvsig.online.lib.api.OnlineManager.OP_INSERT; |
39 |
import static org.gvsig.online.lib.api.OnlineManager.OP_UNKNOWN; |
40 |
import static org.gvsig.online.lib.api.OnlineManager.OP_UPDATE; |
41 |
import static org.gvsig.online.lib.api.OnlineManager.STATE_CONFLICT; |
42 |
import static org.gvsig.online.lib.api.OnlineManager.STATE_LOCAL_MODIFIED; |
43 |
import static org.gvsig.online.lib.api.OnlineManager.STATE_LOCAL_NEW; |
44 |
import static org.gvsig.online.lib.api.OnlineManager.STATE_LOCAL_UNMODIFIED; |
45 |
import org.gvsig.online.lib.api.OnlineRuntimeException; |
46 |
import org.gvsig.online.lib.impl.OnlineUtils; |
47 |
import org.gvsig.online.lib.impl.workspace.tables.RemoteChangesTable.RemoteChangeRow; |
48 |
import org.gvsig.tools.dataTypes.DataTypes; |
49 |
import org.gvsig.tools.dispose.DisposableIterable; |
50 |
import org.gvsig.tools.dispose.DisposeUtils; |
51 |
import org.gvsig.tools.dynobject.DynObjectValueItem; |
52 |
import org.gvsig.tools.util.GetItemWithSize64; |
53 |
import org.gvsig.tools.util.GetItemWithSizeAndIterator64; |
54 |
import org.gvsig.online.lib.api.workingcopy.OnlineWorkingcopy; |
55 |
import org.gvsig.online.lib.api.workingcopy.OnlineWorkingcopyChange; |
56 |
|
57 |
/**
|
58 |
*
|
59 |
* @author gvSIG Team
|
60 |
*/
|
61 |
@SuppressWarnings("UseSpecificCatch") |
62 |
public class WorkspaceChangesTable extends AbstractTable { |
63 |
|
64 |
|
65 |
public static final String TABLE_NAME = "ONLINE_WSCHANGES"; |
66 |
|
67 |
public static final String COD_CHANGE = "COD_WSCHANGE"; |
68 |
public static final String COD_ENTITY = "COD_ENTITY"; |
69 |
public static final String SELECTED = "WSCH_SELECTED"; |
70 |
public static final String FEATUREID = "WSCH_FEATURECODE"; |
71 |
public static final String OPERATION = "WSCH_OPERATION"; |
72 |
public static final String PREVIOUS_OPERATION = "WSCH_PREVOPERATION"; |
73 |
public static final String STATUS = "WSCH_STATUS"; |
74 |
private static final String FEATURE_DATA = "WSCH_DATA"; |
75 |
private static final String EDITING_SESSION = "WSCH_EDITINGSESSION"; |
76 |
|
77 |
private static final String LABEL = "WSCH_LABEL"; |
78 |
private static final int MAX_SIZE_LABEL = 40; |
79 |
|
80 |
@SuppressWarnings("UseSpecificCatch") |
81 |
public static class WorkspaceChangeRow extends AbstractRow implements OnlineWorkingcopyChange { |
82 |
|
83 |
protected OnlineEntity entity;
|
84 |
|
85 |
public WorkspaceChangeRow(OnlineWorkingcopy workspace) {
|
86 |
this(workspace, null); |
87 |
setStatus(OnlineManager.STATE_LOCAL_UNMODIFIED); |
88 |
} |
89 |
|
90 |
public WorkspaceChangeRow(OnlineWorkingcopy workspace, Feature feature) {
|
91 |
super(workspace, TABLE_NAME, COD_CHANGE, feature);
|
92 |
} |
93 |
|
94 |
@Override
|
95 |
public String getEntityCode() { |
96 |
return this.getString(COD_ENTITY); |
97 |
} |
98 |
|
99 |
@Override
|
100 |
public long getRelatedFeatureCode() { |
101 |
return this.getLong(FEATUREID); |
102 |
} |
103 |
|
104 |
@Override
|
105 |
public int getOperation() { |
106 |
return this.getInt(OPERATION); |
107 |
} |
108 |
|
109 |
@Override
|
110 |
public String getOperationLabel() { |
111 |
return this.getLabelOfValue(OPERATION); |
112 |
} |
113 |
|
114 |
@Override
|
115 |
public String getLabel() { |
116 |
return this.getString(LABEL); |
117 |
} |
118 |
|
119 |
@Override
|
120 |
public boolean isSelected() { |
121 |
return this.getBoolean(SELECTED); |
122 |
} |
123 |
|
124 |
public void setEntityCode(String code) { |
125 |
this.set(COD_ENTITY, code);
|
126 |
} |
127 |
|
128 |
public void setFeatureCode(long code) { |
129 |
this.set(FEATUREID, code);
|
130 |
} |
131 |
|
132 |
public void setOperation(int op) { |
133 |
this.set(OPERATION, op);
|
134 |
} |
135 |
|
136 |
public void setStatus(int status) { |
137 |
this.set(STATUS, status);
|
138 |
} |
139 |
|
140 |
@Override
|
141 |
public void setSelected(boolean selected) { |
142 |
this.set(SELECTED, selected);
|
143 |
} |
144 |
|
145 |
public void setLabel(String label) { |
146 |
this.set(LABEL, StringUtils.abbreviate(label, MAX_SIZE_LABEL));
|
147 |
} |
148 |
|
149 |
@Override
|
150 |
public String getRelatedFeatureData() { |
151 |
String entityName = "unknown"; |
152 |
long code = 0; |
153 |
FeatureStore store = null;
|
154 |
try {
|
155 |
entityName = this.getEntity().getEntityName();
|
156 |
code = this.getRelatedFeatureCode();
|
157 |
store = workspace.getFeatureStore(entityName); |
158 |
Feature f = store.findFirst("\""+this.getEntity().getFeatureIdFieldName()+"\"="+code); |
159 |
if( f==null ) { |
160 |
int op = this.getOperation(); |
161 |
if( op == OnlineManager.OP_INSERT || op == OnlineManager.OP_UPDATE ) {
|
162 |
LOGGER.warn("Can't retrieve feature data for an insert or update operation (ENT/VCSGISCODE='"+entityName+"/"+code+"')"); |
163 |
throw new RuntimeException("Feature ENT/VCSGISCODE='"+entityName+"/"+code+"'not found."); |
164 |
} |
165 |
return ""; //null; |
166 |
// throw new RuntimeException("Feature '"+entityName+"/"+code+"'not found.");
|
167 |
} |
168 |
JsonObject json = f.toJson(); |
169 |
// JsonObject json = f.toJson(Collections.singletonMap("geometryformat", this.workspace.getGeometryFormat()));
|
170 |
String data = json.toString();
|
171 |
return data;
|
172 |
} catch (Exception ex) { |
173 |
LOGGER.warn("Can't retrieve feature data (ENT/ONLINECODE='"+entityName+"/"+code+"')"); |
174 |
throw new RuntimeException("Can't retrieve feature data of ENT/ONLINECODE='"+entityName+"/"+code+"'.",ex); |
175 |
} finally {
|
176 |
DisposeUtils.disposeQuietly(store); |
177 |
} |
178 |
} |
179 |
|
180 |
@Override
|
181 |
public JsonObject getRelatedFeatureDataAsJson() {
|
182 |
String s = this.getRelatedFeatureData(); |
183 |
return Json.createObject(s);
|
184 |
} |
185 |
|
186 |
@Override
|
187 |
public String toString() { |
188 |
switch (this.getOperation()) { |
189 |
// case OnlineManager.OP_ADD_ENTITY:
|
190 |
// return "{ OP:'ADD_ENTITY', ENTITYCODE:'"+this.getEntityCode()+"', }";
|
191 |
case OnlineManager.OP_INSERT:
|
192 |
return "{ OP:'INSERT', ENTITYCODE:'"+this.getEntityCode()+"', FEATURECODE:'"+this.getRelatedFeatureCode()+"', DATA:'"+this.getRelatedFeatureData()+"' }"; |
193 |
case OnlineManager.OP_UPDATE:
|
194 |
return "{ OP:'UPDATE', ENTITYCODE:'"+this.getEntityCode()+"', FEATURECODE:'"+this.getRelatedFeatureCode()+"', DATA:'"+this.getRelatedFeatureData()+"' }"; |
195 |
case OnlineManager.OP_DELETE:
|
196 |
return "{ OP:'DELETE', ENTITYCODE:'"+this.getEntityCode()+"', FEATURECODE:'"+this.getRelatedFeatureCode()+"' }"; |
197 |
default:
|
198 |
return "{ OP:'"+this.getOperation()+"', ENTITYCODE:'"+this.getEntityCode()+"', FEATURECODE:'"+this.getRelatedFeatureCode()+"' }"; |
199 |
} |
200 |
} |
201 |
|
202 |
@Override
|
203 |
public Feature getRelatedFeature() {
|
204 |
Feature f = this.workspace.getRelatedFeature(this.getEntity(), this.getRelatedFeatureCode()); |
205 |
if (f == null) { |
206 |
throw new RuntimeException("Feature '" + this.getEntity().getEntityName() + "/" + this.getRelatedFeatureCode() + "'not found."); |
207 |
} |
208 |
return f;
|
209 |
} |
210 |
|
211 |
public OnlineEntity getEntity() {
|
212 |
if( this.entity == null ) { |
213 |
this.entity = this.workspace.getWorkspaceEntityByCode(this.getEntityCode()); |
214 |
} |
215 |
return this.entity; |
216 |
} |
217 |
|
218 |
@Override
|
219 |
public int getStatus() { |
220 |
return this.getInt(STATUS); |
221 |
} |
222 |
|
223 |
@Override
|
224 |
public void update(FeatureStore store) { |
225 |
this.updateStatus();
|
226 |
super.update(store);
|
227 |
} |
228 |
|
229 |
@Override
|
230 |
public void insert(FeatureStore store) { |
231 |
this.updateStatus();
|
232 |
super.insert(store);
|
233 |
} |
234 |
|
235 |
private void updateStatus() { |
236 |
if(getStatus() == OnlineManager.STATE_LOCAL_UNMODIFIED){
|
237 |
switch(this.getOperation()){ |
238 |
case OnlineManager.OP_INSERT:
|
239 |
// case OnlineManager.OP_ADD_ENTITY:
|
240 |
setStatus(OnlineManager.STATE_LOCAL_NEW); |
241 |
return;
|
242 |
case OnlineManager.OP_DELETE:
|
243 |
case OnlineManager.OP_UPDATE:
|
244 |
setStatus(OnlineManager.STATE_LOCAL_MODIFIED); |
245 |
return;
|
246 |
} |
247 |
} |
248 |
} |
249 |
|
250 |
public void revert(FeatureStore userStore, FeatureStore changesStore) throws DataException { |
251 |
long code = this.getRelatedFeatureCode(); |
252 |
EditableFeature editable; |
253 |
switch (this.getOperation()) { |
254 |
case OnlineManager.OP_INSERT:
|
255 |
userStore.delete("\""+FEATURECODE_FIELD_NAME+"\" = "+code); |
256 |
changesStore.delete("\""+COD_CHANGE+"\" = '"+this.getCode()+"'"); |
257 |
break;
|
258 |
// case OnlineManager.OP_ADD_ENTITY:
|
259 |
// break;
|
260 |
case OnlineManager.OP_UPDATE:
|
261 |
Feature feat = userStore.findFirst("\""+FEATURECODE_FIELD_NAME+"\" = "+code); |
262 |
if(feat == null) { |
263 |
throw new OnlineRuntimeException(1, "xxx"); |
264 |
} |
265 |
editable = feat.getEditable(); |
266 |
editable.copyFrom(this.getDataAsJson());
|
267 |
userStore.update(editable); |
268 |
changesStore.delete("\""+COD_CHANGE+"\" = '"+this.getCode()+"'"); |
269 |
break;
|
270 |
case OnlineManager.OP_DELETE:
|
271 |
editable = userStore.createNewFeature(this.getDataAsJson());
|
272 |
userStore.insert(editable); |
273 |
changesStore.delete("\""+COD_CHANGE+"\" = '"+this.getCode()+"'"); |
274 |
break;
|
275 |
} |
276 |
} |
277 |
|
278 |
public void setData(String data) { |
279 |
this.set(FEATURE_DATA, data);
|
280 |
} |
281 |
|
282 |
@Override
|
283 |
public String getData() { |
284 |
return this.getString(FEATURE_DATA); |
285 |
} |
286 |
|
287 |
@Override
|
288 |
public JsonObject getDataAsJson() {
|
289 |
String s = this.getData(); |
290 |
return Json.createObject(s);
|
291 |
} |
292 |
|
293 |
public void setEditingSession(String editingSession) { |
294 |
this.set(EDITING_SESSION, editingSession);
|
295 |
} |
296 |
|
297 |
public void setPreviousOperation(int operation) { |
298 |
this.set(PREVIOUS_OPERATION, operation);
|
299 |
} |
300 |
} |
301 |
|
302 |
public WorkspaceChangesTable() {
|
303 |
super(TABLE_NAME, featureType());
|
304 |
} |
305 |
|
306 |
public DisposableFeatureSetIterable getByOperation(OnlineWorkingcopy workspace, int op) { |
307 |
return getByOperation(workspace, null, op); |
308 |
// FeatureStore store = null;
|
309 |
// try {
|
310 |
// store = workspace.getFeatureStore(TABLE_NAME);
|
311 |
// FeatureQuery query = store.createFeatureQuery();
|
312 |
// query.addFilter("\""+WorkspaceChangesTable.OPERATION+"\"="+op);
|
313 |
// query.retrievesAllAttributes();
|
314 |
// DisposableFeatureSetIterable changes = store.getFeatureSet(query).iterable();
|
315 |
// return changes;
|
316 |
// } catch (Exception ex) {
|
317 |
// throw new RuntimeException("Can't retrieve changes for operartion "+op+".", ex);
|
318 |
// } finally {
|
319 |
// if( store!=null ) {
|
320 |
// DisposeUtils.dispose(store);
|
321 |
// }
|
322 |
// }
|
323 |
} |
324 |
|
325 |
public DisposableFeatureSetIterable getByOperation(OnlineWorkingcopy workspace, String entityCode, int op) { |
326 |
FeatureStore store = null;
|
327 |
try {
|
328 |
store = workspace.getFeatureStore(TABLE_NAME); |
329 |
FeatureQuery query = store.createFeatureQuery(); |
330 |
if( !StringUtils.isBlank(entityCode) ) {
|
331 |
query.addFilter("\""+COD_ENTITY+"\" ='"+entityCode+"' AND \""+WorkspaceChangesTable.OPERATION+"\"="+op); |
332 |
} else {
|
333 |
query.addFilter("\""+WorkspaceChangesTable.OPERATION+"\"="+op); |
334 |
} |
335 |
|
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 for operartion "+op+".", ex); |
341 |
} finally {
|
342 |
if( store!=null ) { |
343 |
DisposeUtils.dispose(store); |
344 |
} |
345 |
} |
346 |
} |
347 |
|
348 |
|
349 |
public DisposableFeatureSetIterable getGroupedByEntity(OnlineWorkingcopy workspace) {
|
350 |
FeatureStore store = null;
|
351 |
try {
|
352 |
store = workspace.getFeatureStore(TABLE_NAME); |
353 |
FeatureQuery query = store.createFeatureQuery(); |
354 |
|
355 |
query.getOrder().add(WorkspaceChangesTable.COD_ENTITY,true);
|
356 |
query.getGroupByColumns().add(WorkspaceChangesTable.COD_ENTITY); |
357 |
query.getAggregateFunctions().put(SELECTED, "MAX");
|
358 |
query.retrievesAllAttributes(); |
359 |
DisposableFeatureSetIterable changes = store.getFeatureSet(query).iterable(); |
360 |
return changes;
|
361 |
} catch (Exception ex) { |
362 |
throw new RuntimeException("Can't retrieve changes grouped by entity.", ex); |
363 |
} finally {
|
364 |
if( store!=null ) { |
365 |
DisposeUtils.dispose(store); |
366 |
} |
367 |
} |
368 |
} |
369 |
|
370 |
// public DisposableFeatureSetIterable getSelectedsWithoutAddEntity(OnlineWorkingcopy workspace) {
|
371 |
// return getSelectedsWithoutAddEntity(workspace, null);
|
372 |
// }
|
373 |
//
|
374 |
// public DisposableFeatureSetIterable getSelectedsWithoutAddEntity(OnlineWorkingcopy workspace, List<String> entityCodes) {
|
375 |
// FeatureStore store = null;
|
376 |
// try {
|
377 |
// store = workspace.getFeatureStore(TABLE_NAME);
|
378 |
// FeatureQuery query = store.createFeatureQuery();
|
379 |
//
|
380 |
// if(CollectionUtils.isEmpty(entityCodes)){
|
381 |
// query.setFilter("\""+SELECTED+"\" AND \""
|
382 |
//// +OPERATION+"\" <> "+OnlineManager.OP_ADD_ENTITY+" AND \""
|
383 |
// +OPERATION+"\" <> "+OnlineManager.OP_IGNORE);
|
384 |
// } else {
|
385 |
// ExpressionBuilder expBuilder = ExpressionUtils.createExpressionBuilder();
|
386 |
// for (String entityCode : entityCodes) {
|
387 |
// expBuilder.or(expBuilder.eq(expBuilder.column(COD_ENTITY), expBuilder.constant(entityCode)));
|
388 |
// }
|
389 |
// expBuilder.and(expBuilder.column(SELECTED))
|
390 |
//// .and(expBuilder.ne(expBuilder.column(OPERATION), expBuilder.constant(OnlineManager.OP_ADD_ENTITY)))
|
391 |
// .and(expBuilder.ne(expBuilder.column(OPERATION), expBuilder.constant(OnlineManager.OP_IGNORE)));
|
392 |
// query.setFilter(expBuilder.value().toString());
|
393 |
// }
|
394 |
//
|
395 |
// query.retrievesAllAttributes();
|
396 |
// DisposableFeatureSetIterable changes = store.getFeatureSet(query).iterable();
|
397 |
// if( changes.isEmpty() ) {
|
398 |
// DisposeUtils.disposeQuietly(changes);
|
399 |
// return null;
|
400 |
// }
|
401 |
// return changes;
|
402 |
// } catch (Exception ex) {
|
403 |
// throw new RuntimeException("Can't retrieve all changes.", ex);
|
404 |
// } finally {
|
405 |
// DisposeUtils.disposeQuietly(store);
|
406 |
// }
|
407 |
// }
|
408 |
|
409 |
public DisposableFeatureSetIterable getAll(OnlineWorkingcopy workspace) {
|
410 |
FeatureStore store = null;
|
411 |
try {
|
412 |
store = workspace.getFeatureStore(TABLE_NAME); |
413 |
DisposableFeatureSetIterable changes = store.getFeatureSet().iterable(); |
414 |
return changes;
|
415 |
} catch (Exception ex) { |
416 |
throw new RuntimeException("Can't retrieve all changes.", ex); |
417 |
} finally {
|
418 |
DisposeUtils.disposeQuietly(store); |
419 |
} |
420 |
} |
421 |
|
422 |
public GetItemWithSize64<Feature> getByEntityCode(OnlineWorkingcopy workspace, List<OnlineEntity> entities) { |
423 |
FeatureStore store = null;
|
424 |
try {
|
425 |
store = workspace.getFeatureStore(TABLE_NAME); |
426 |
if( CollectionUtils.isEmpty(entities) ) {
|
427 |
GetItemWithSizeAndIterator64<Feature> changes = store.getFeatures64( |
428 |
null,
|
429 |
"\""+COD_ENTITY+"\",-\""+OPERATION+"\",\""+COD_CHANGE+"\"", |
430 |
true);
|
431 |
return changes;
|
432 |
} |
433 |
ExpressionBuilder exprBuilder = ExpressionUtils.createExpressionBuilder(); |
434 |
for (OnlineEntity entity : entities) {
|
435 |
exprBuilder.or(exprBuilder.eq(exprBuilder.column(COD_ENTITY), exprBuilder.constant(entity.getEntityCode()))); |
436 |
} |
437 |
GetItemWithSizeAndIterator64<Feature> changes = store.getFeatures64( |
438 |
exprBuilder.value().toString(), |
439 |
"\""+COD_ENTITY+"\",-\""+OPERATION+"\",\""+COD_CHANGE+"\"", |
440 |
true
|
441 |
); |
442 |
return changes;
|
443 |
} catch (Exception ex) { |
444 |
throw new RuntimeException("Can't retrieve changes by entity.", ex); |
445 |
} finally {
|
446 |
DisposeUtils.disposeQuietly(store); |
447 |
} |
448 |
} |
449 |
|
450 |
public boolean hasLocalChangesByEntityCode(OnlineWorkingcopy workspace, List<OnlineEntity> entities) { |
451 |
FeatureStore store = null;
|
452 |
try {
|
453 |
store = workspace.getFeatureStore(TABLE_NAME); |
454 |
if( CollectionUtils.isEmpty(entities) ) {
|
455 |
Feature f = store.findFirst((FeatureQuery)null);
|
456 |
return f!=null; |
457 |
} |
458 |
ExpressionBuilder exprBuilder = ExpressionUtils.createExpressionBuilder(); |
459 |
for (OnlineEntity entity : entities) {
|
460 |
exprBuilder.or(exprBuilder.eq(exprBuilder.column(COD_ENTITY), exprBuilder.constant(entity.getEntityCode()))); |
461 |
} |
462 |
Feature f = store.findFirst(exprBuilder.value().toString()); |
463 |
return f!=null; |
464 |
} catch (Exception ex) { |
465 |
throw new RuntimeException("Can't retrieve changes by entity.", ex); |
466 |
} finally {
|
467 |
DisposeUtils.disposeQuietly(store); |
468 |
} |
469 |
} |
470 |
|
471 |
public long getCountLocalChangesOfEntity(OnlineWorkingcopy workspace, String entityCode) { |
472 |
return this.getCountLocalChangesOfEntity(workspace, null, entityCode); |
473 |
} |
474 |
|
475 |
public long getCountLocalChangesOfEntity(OnlineWorkingcopy workspace, DataTransaction transaction, String entityCode) { |
476 |
FeatureStore store = null;
|
477 |
FeatureSet changes = null;
|
478 |
try {
|
479 |
if( transaction==null ) { |
480 |
store = workspace.getFeatureStore(TABLE_NAME); |
481 |
} else {
|
482 |
store = transaction.getFeatureStore(TABLE_NAME); |
483 |
if( store == null ) { |
484 |
store = workspace.getFeatureStore(TABLE_NAME); |
485 |
} else {
|
486 |
DisposeUtils.bind(store); |
487 |
} |
488 |
} |
489 |
if( StringUtils.isBlank(entityCode) ) {
|
490 |
throw new IllegalArgumentException("entityCode is required."); |
491 |
} |
492 |
changes = store.getFeatureSet( |
493 |
"\""+COD_ENTITY+"\"='"+entityCode+"'" |
494 |
); |
495 |
return changes.size64();
|
496 |
} catch (Exception ex) { |
497 |
throw new RuntimeException("Can't retrieve changes by entity.", ex); |
498 |
} finally {
|
499 |
DisposeUtils.disposeQuietly(changes); |
500 |
DisposeUtils.disposeQuietly(store); |
501 |
} |
502 |
} |
503 |
|
504 |
public WorkspaceChangeRow getByEntityAndDataCode(
|
505 |
OnlineWorkingcopy workspace, |
506 |
String entityCode,
|
507 |
String featureCode,
|
508 |
FeatureStore localChangesStore |
509 |
) { |
510 |
FeatureStore store = localChangesStore; |
511 |
try {
|
512 |
if(store == null){ |
513 |
store = workspace.getFeatureStore(TABLE_NAME); |
514 |
} |
515 |
Feature f = store.findFirst( |
516 |
"\"" + COD_ENTITY + "\"='" + entityCode + "' AND \""+FEATUREID+"\"='"+featureCode+"'" |
517 |
); |
518 |
if (f == null) { |
519 |
return null; |
520 |
} |
521 |
WorkspaceChangeRow row = new WorkspaceChangeRow(workspace, f);
|
522 |
return row;
|
523 |
} catch (Exception ex) { |
524 |
throw new RuntimeException("Can't retrieve change for 'FEATURECODE[" + featureCode + "]'.", ex); |
525 |
} finally {
|
526 |
if(localChangesStore == null){ |
527 |
DisposeUtils.disposeQuietly(store); |
528 |
} |
529 |
} |
530 |
} |
531 |
|
532 |
public void deleteAll(OnlineWorkingcopy workspace) { |
533 |
FeatureStore store = null;
|
534 |
try {
|
535 |
store = workspace.openFeatureStore(TABLE_NAME, true);
|
536 |
store.edit(MODE_PASS_THROUGH); |
537 |
store.delete("TRUE");
|
538 |
store.finishEditing(); |
539 |
} catch (Exception ex) { |
540 |
FeatureStore.cancelEditingQuietly(store); |
541 |
throw new RuntimeException("Can't delete all changes.", ex); |
542 |
} finally {
|
543 |
if( store!=null ) { |
544 |
DisposeUtils.dispose(store); |
545 |
} |
546 |
} |
547 |
} |
548 |
|
549 |
public void deleteSelecteds(OnlineWorkingcopy workspace, List<String> entityCodes) { |
550 |
FeatureStore store = null;
|
551 |
try {
|
552 |
store = workspace.openFeatureStore(TABLE_NAME, true);
|
553 |
store.edit(MODE_PASS_THROUGH); |
554 |
ExpressionBuilder expBuilder = ExpressionUtils.createExpressionBuilder(); |
555 |
if(CollectionUtils.isNotEmpty(entityCodes)){
|
556 |
for (String entityCode : entityCodes) { |
557 |
expBuilder.or(expBuilder.eq(expBuilder.column(COD_ENTITY), expBuilder.constant(entityCode))); |
558 |
} |
559 |
} |
560 |
expBuilder.and(expBuilder.column(SELECTED)); |
561 |
|
562 |
store.delete(expBuilder.value().toString()); |
563 |
store.finishEditing(); |
564 |
} catch (Exception ex) { |
565 |
FeatureStore.cancelEditingQuietly(store); |
566 |
throw new RuntimeException("Can't delete selected changes.", ex); |
567 |
} finally {
|
568 |
if( store!=null ) { |
569 |
DisposeUtils.dispose(store); |
570 |
} |
571 |
} |
572 |
} |
573 |
|
574 |
public void deleteByEntity(OnlineWorkingcopy workspace, String entityCode) { |
575 |
FeatureStore store = null;
|
576 |
try {
|
577 |
store = workspace.openFeatureStore(TABLE_NAME, true);
|
578 |
store.edit(MODE_PASS_THROUGH); |
579 |
store.delete("\""+COD_ENTITY+"\"='"+entityCode+"'"); |
580 |
store.finishEditing(); |
581 |
} catch (Exception ex) { |
582 |
FeatureStore.cancelEditingQuietly(store); |
583 |
throw new RuntimeException("Can't delete selected changes.", ex); |
584 |
} finally {
|
585 |
if( store!=null ) { |
586 |
DisposeUtils.dispose(store); |
587 |
} |
588 |
} |
589 |
} |
590 |
|
591 |
public DisposableFeatureSetIterable getSelectedsByEntityCodeAsIterator(OnlineWorkingcopy workspace, String entityCode) { |
592 |
FeatureStore store = null;
|
593 |
try {
|
594 |
store = workspace.getFeatureStore(TABLE_NAME); |
595 |
FeatureSet changes; |
596 |
if( StringUtils.isBlank(entityCode) ) {
|
597 |
changes = store.getFeatureSet("\""+SELECTED+"\""); |
598 |
} else {
|
599 |
changes = store.getFeatureSet("\""+SELECTED+"\" AND \""+COD_ENTITY+"\"='"+entityCode+"'"); |
600 |
} |
601 |
return changes.iterable();
|
602 |
} catch (Exception ex) { |
603 |
throw new RuntimeException("Can't retrieve selected remote changes by entity code (ENTITY["+entityCode+"]).", ex); |
604 |
} finally {
|
605 |
if( store!=null ) { |
606 |
DisposeUtils.dispose(store); |
607 |
} |
608 |
} |
609 |
} |
610 |
|
611 |
|
612 |
public void deleteSelectedsByEntity(OnlineWorkingcopy workspace, String entityCode) { |
613 |
FeatureStore store = null;
|
614 |
try {
|
615 |
store = workspace.openFeatureStore(TABLE_NAME, true);
|
616 |
store.edit(MODE_PASS_THROUGH); |
617 |
store.delete("\""+COD_ENTITY+"\"='"+entityCode+"'"+" AND "+"\""+SELECTED+"\""); |
618 |
store.finishEditing(); |
619 |
} catch (Exception ex) { |
620 |
FeatureStore.cancelEditingQuietly(store); |
621 |
throw new RuntimeException("Can't delete selected changes.", ex); |
622 |
} finally {
|
623 |
if( store!=null ) { |
624 |
DisposeUtils.dispose(store); |
625 |
} |
626 |
} |
627 |
} |
628 |
|
629 |
public WorkspaceChangeRow find(OnlineWorkingcopy workspace, FeatureStore store, String entityCode, long featureCode) { |
630 |
try {
|
631 |
Feature f = store.findFirst( |
632 |
// "\""+FEATUREID+"\"='"+featureCode+"'"
|
633 |
"\""+COD_ENTITY+"\"='"+entityCode+"' AND \""+FEATUREID+"\"="+featureCode |
634 |
); |
635 |
if(f==null){ |
636 |
return null; |
637 |
} |
638 |
return new WorkspaceChangeRow(workspace, f); |
639 |
} catch (Exception ex) { |
640 |
throw new RuntimeException("Can't retrieve change.", ex); |
641 |
} |
642 |
} |
643 |
|
644 |
public static final FeatureType featureType() { |
645 |
DataManager dataManager = DALLocator.getDataManager(); |
646 |
EditableFeatureType ft = dataManager.createFeatureType(); |
647 |
ft.setLabel("Online Local changes");
|
648 |
ft.getTags().set("ID", TABLE_NAME);
|
649 |
ft.add(COD_CHANGE, DataTypes.STRING) |
650 |
.setSize(ONLINECODELEN) |
651 |
.setIsPrimaryKey(true)
|
652 |
.setLabel("Code")
|
653 |
.setReadOnly(false);
|
654 |
ft.add(COD_ENTITY, DataTypes.STRING) |
655 |
// .setIsIndexed(true)
|
656 |
.setAllowIndexDuplicateds(true)
|
657 |
.setSize(ONLINECODELEN) |
658 |
.setLabel("Entity code");
|
659 |
ft.add(SELECTED, DataTypes.BOOLEAN) |
660 |
// .setIsIndexed(true)
|
661 |
.setAllowIndexDuplicateds(true)
|
662 |
.setLabel("Selected");
|
663 |
ft.add(EDITING_SESSION, DataTypes.STRING) |
664 |
.setIsIndexed(true)
|
665 |
.setAllowIndexDuplicateds(true)
|
666 |
.setLabel("Editing session");
|
667 |
ft.add(FEATUREID, DataTypes.LONG) |
668 |
.setIsIndexed(true)
|
669 |
.setLabel("Identifier")
|
670 |
.setDescription("The identifier of the feature");
|
671 |
ft.add(OPERATION, DataTypes.INTEGER) |
672 |
.setIsIndexed(true)
|
673 |
.setLabel("Operation")
|
674 |
.setAvailableValues(new DynObjectValueItem[] { |
675 |
// new DynObjectValueItem(OP_ADD_ENTITY, "Add entity"),
|
676 |
new DynObjectValueItem(OP_INSERT, "Insert"), |
677 |
new DynObjectValueItem(OP_UPDATE, "Update"), |
678 |
new DynObjectValueItem(OP_DELETE, "Delete"), |
679 |
new DynObjectValueItem(OP_IGNORE, "Ignore") |
680 |
}); |
681 |
ft.add(PREVIOUS_OPERATION, DataTypes.INTEGER) |
682 |
.setIsIndexed(true)
|
683 |
.setLabel("Operation")
|
684 |
.setAvailableValues(new DynObjectValueItem[] { |
685 |
new DynObjectValueItem(OP_INSERT, "Insert"), |
686 |
new DynObjectValueItem(OP_UPDATE, "Update"), |
687 |
new DynObjectValueItem(OP_UNKNOWN, "Unknown") |
688 |
}); |
689 |
ft.add(STATUS, DataTypes.INTEGER) |
690 |
.setLabel("Status")
|
691 |
.setAvailableValues(new DynObjectValueItem[] { |
692 |
new DynObjectValueItem(STATE_LOCAL_NEW, "New"), |
693 |
new DynObjectValueItem(STATE_LOCAL_UNMODIFIED, "Unmodified"), |
694 |
new DynObjectValueItem(STATE_LOCAL_MODIFIED, "Modified"), |
695 |
new DynObjectValueItem(STATE_CONFLICT, "Conflict") |
696 |
}); |
697 |
ft.add(LABEL, DataTypes.STRING) |
698 |
.setIsIndexed(false)
|
699 |
.setSize(MAX_SIZE_LABEL) |
700 |
.setLabel("Label")
|
701 |
.setDescription("The label of the feature");
|
702 |
ft.add(FEATURE_DATA, DataTypes.STRING) |
703 |
.setSize(RECOMENDED_SIZE_FOR_CLOB) |
704 |
.setLabel("Data");
|
705 |
|
706 |
return ft.getNotEditableCopy();
|
707 |
} |
708 |
|
709 |
public void removeLocalChangesRelatedToSelectedRemoteChanges(OnlineWorkingcopy workspace, OnlineEntity lentity) { |
710 |
String sql = String.format(OnlineUtils.getSqlTemplate(workspace.getExplorer().getProviderName(), "removeLocalChangesRelatedToSelectedRemoteChanges"), lentity.getEntityCode()); |
711 |
Object res = workspace.getExplorer().execute(sql);
|
712 |
} |
713 |
|
714 |
public void removeLocalChanges(OnlineWorkingcopy workspace, OnlineEntity lentity, String editingSession) { |
715 |
FeatureStore store = null;
|
716 |
try {
|
717 |
store = workspace.openFeatureStore(TABLE_NAME, true);
|
718 |
store.edit(FeatureStore.MODE_PASS_THROUGH); |
719 |
store.delete("\""+EDITING_SESSION+"\" = '"+editingSession+"'"); |
720 |
store.finishEditingQuietly(); |
721 |
} catch (Exception ex) { |
722 |
FeatureStore.cancelEditingQuietly(store); |
723 |
throw new RuntimeException("Can't remove local changes.", ex); |
724 |
} finally {
|
725 |
DisposeUtils.disposeQuietly(store); |
726 |
} |
727 |
} |
728 |
|
729 |
public void revertChangedLocalChanges(OnlineWorkingcopy workspace, OnlineEntity lentity, String editingSession) { |
730 |
FeatureStore store = null;
|
731 |
FeatureSet features = null;
|
732 |
try {
|
733 |
store = workspace.openFeatureStore(TABLE_NAME, true);
|
734 |
store.edit(FeatureStore.MODE_PASS_THROUGH); |
735 |
features = store.getFeatureSet("\""+EDITING_SESSION+"\" = '"+editingSession+"' and \""+PREVIOUS_OPERATION+"\" <> "+OP_UNKNOWN); |
736 |
for (Feature feature : features) {
|
737 |
EditableFeature eFeature = feature.getEditable(); |
738 |
eFeature.set(OPERATION, eFeature.get(PREVIOUS_OPERATION)); |
739 |
eFeature.set(PREVIOUS_OPERATION, OP_UNKNOWN); |
740 |
store.update(eFeature); |
741 |
} |
742 |
store.finishEditingQuietly(); |
743 |
} catch (Exception ex) { |
744 |
FeatureStore.cancelEditingQuietly(store); |
745 |
throw new RuntimeException("Can't remove local changes.", ex); |
746 |
} finally {
|
747 |
DisposeUtils.disposeQuietly(features); |
748 |
DisposeUtils.disposeQuietly(store); |
749 |
} |
750 |
}; |
751 |
|
752 |
public void removeIgnoredLocalChanges(OnlineWorkingcopy workspace, OnlineEntity lentity, String editingSession) { |
753 |
FeatureStore store = null;
|
754 |
try {
|
755 |
store = workspace.openFeatureStore(TABLE_NAME, true);
|
756 |
store.edit(FeatureStore.MODE_PASS_THROUGH); |
757 |
store.delete("\""+EDITING_SESSION+"\" = '"+editingSession+"' and \""+OPERATION+"\" = "+OP_IGNORE); |
758 |
store.finishEditingQuietly(); |
759 |
} catch (Exception ex) { |
760 |
FeatureStore.cancelEditingQuietly(store); |
761 |
throw new RuntimeException("Can't remove local changes.", ex); |
762 |
} finally {
|
763 |
DisposeUtils.disposeQuietly(store); |
764 |
} |
765 |
}; |
766 |
|
767 |
public DisposableIterable<WorkspaceChangeRow> getChangesWidthUserData(OnlineWorkingcopy workspace, OnlineEntity lentity, RemoteChangeRow remoteChange, FeatureStore localChangesStore, DataTransaction transaction) {
|
768 |
|
769 |
FeatureType featType = lentity.getFeatureType(); |
770 |
JsonObject data = remoteChange.getRelatedFeatureDataAsJson(); |
771 |
ExpressionEvaluatorManager expManager = ExpressionEvaluatorLocator.getManager(); |
772 |
ExpressionBuilder builder = expManager.createExpressionBuilder(); |
773 |
builder.set(null);
|
774 |
for (FeatureAttributeDescriptor attr : featType) {
|
775 |
if(StringUtils.equalsAnyIgnoreCase(lentity.getFeatureIdFieldName(),attr.getName())){
|
776 |
continue;
|
777 |
} |
778 |
if(attr.isIndexed() && !attr.allowIndexDuplicateds()){
|
779 |
Object value = Json.toObject(data, attr.getName());
|
780 |
builder.or( |
781 |
builder.eq( |
782 |
builder.column(attr.getName()), |
783 |
builder.constant(value) |
784 |
) |
785 |
); |
786 |
} |
787 |
} |
788 |
ExpressionBuilder.Value value = builder.value(); |
789 |
if(value == null){ |
790 |
return null; |
791 |
} |
792 |
|
793 |
JDBCServerExplorer serverExplorer = workspace.getExplorer(); |
794 |
String sql = String.format( |
795 |
OnlineUtils.getSqlTemplate( |
796 |
workspace.getExplorer().getProviderName(), |
797 |
"getChangesWidthUserData"
|
798 |
), |
799 |
lentity.getEntityName(), |
800 |
lentity.getFeatureIdFieldName(), |
801 |
remoteChange.getRelatedFeatureCode(), |
802 |
builder.toString() |
803 |
); |
804 |
|
805 |
final ResultSet rs = (ResultSet) serverExplorer.execute(sql); |
806 |
if(rs == null){ |
807 |
return null; |
808 |
} |
809 |
final WorkspaceChangeRow row;
|
810 |
try {
|
811 |
row = new WorkspaceChangeRow(workspace, localChangesStore.createNewFeature());
|
812 |
} catch (DataException ex) {
|
813 |
try {
|
814 |
rs.close(); |
815 |
} catch (SQLException ex2) { |
816 |
} |
817 |
return null; |
818 |
} |
819 |
DisposableIterable<WorkspaceChangeRow> r = new DisposableIterable<WorkspaceChangeRow>() {
|
820 |
@Override
|
821 |
public Iterator<WorkspaceChangeRow> iterator() { |
822 |
Iterator<WorkspaceChangeRow> it = new Iterator<WorkspaceChangeRow>() { |
823 |
@Override
|
824 |
public boolean hasNext() { |
825 |
try {
|
826 |
return rs.next();
|
827 |
} catch (SQLException ex) { |
828 |
return false; |
829 |
} |
830 |
} |
831 |
|
832 |
@Override
|
833 |
public WorkspaceChangeRow next() {
|
834 |
try {
|
835 |
row.setCode(rs.getString(COD_CHANGE)); |
836 |
row.setEntityCode(rs.getString(COD_ENTITY)); |
837 |
row.setFeatureCode(rs.getLong(FEATUREID)); |
838 |
row.setLabel(rs.getString(LABEL)); |
839 |
row.setOperation(rs.getInt(OPERATION)); |
840 |
row.setSelected(rs.getBoolean(SELECTED)); |
841 |
row.setStatus(rs.getInt(STATUS)); |
842 |
return row;
|
843 |
} catch (SQLException ex) { |
844 |
return null; |
845 |
} |
846 |
} |
847 |
}; |
848 |
return it;
|
849 |
} |
850 |
|
851 |
@Override
|
852 |
public void dispose() { |
853 |
try {
|
854 |
Connection conn = rs.getStatement().getConnection();
|
855 |
rs.close(); |
856 |
if(transaction != null && transaction.contains(serverExplorer) && transaction.isInProgress()){ |
857 |
return;
|
858 |
} |
859 |
conn.close(); |
860 |
} catch (SQLException ex) { |
861 |
LOGGER.warn("Can't close resultSet.", ex);
|
862 |
} |
863 |
} |
864 |
}; |
865 |
|
866 |
return r;
|
867 |
} |
868 |
|
869 |
public void changeState(FeatureStore localChangesStore, String entityCode, int searchState, int replaceState) { |
870 |
try {
|
871 |
boolean needFinish = false; |
872 |
if(localChangesStore.getMode() == FeatureStore.MODE_QUERY){
|
873 |
localChangesStore.edit(MODE_PASS_THROUGH); |
874 |
needFinish = true;
|
875 |
} |
876 |
String filter = "\""+COD_ENTITY+"\"='"+entityCode+"' AND \""+STATUS+"\"="+searchState; |
877 |
localChangesStore.update(STATUS,replaceState,filter); |
878 |
if(needFinish) {
|
879 |
localChangesStore.finishEditing(); |
880 |
} |
881 |
} catch (Exception ex) { |
882 |
throw new RuntimeException("Can't change state.", ex); |
883 |
} |
884 |
} |
885 |
|
886 |
|
887 |
} |