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 / VCSGisWorkspaceImpl.java @ 2728
History | View | Annotate | Download (70.9 KB)
1 |
package org.gvsig.vcsgis.lib.workspace; |
---|---|
2 |
|
3 |
import java.io.File; |
4 |
import java.sql.Timestamp; |
5 |
import java.time.LocalDateTime; |
6 |
import java.time.ZoneOffset; |
7 |
import java.util.ArrayList; |
8 |
import java.util.Collection; |
9 |
import java.util.HashMap; |
10 |
import java.util.HashSet; |
11 |
import java.util.Iterator; |
12 |
import java.util.List; |
13 |
import java.util.Map; |
14 |
import java.util.Set; |
15 |
import javax.json.JsonObject; |
16 |
import org.apache.commons.lang3.Range; |
17 |
import org.apache.commons.lang3.StringUtils; |
18 |
import org.gvsig.expressionevaluator.ExpressionBuilder; |
19 |
import org.gvsig.expressionevaluator.ExpressionEvaluatorLocator; |
20 |
import org.gvsig.expressionevaluator.ExpressionEvaluatorManager; |
21 |
import org.gvsig.fmap.dal.DALLocator; |
22 |
import org.gvsig.fmap.dal.DataManager; |
23 |
import org.gvsig.fmap.dal.DataStore; |
24 |
import org.gvsig.fmap.dal.DataStoreParameters; |
25 |
import org.gvsig.fmap.dal.feature.EditableFeature; |
26 |
import org.gvsig.fmap.dal.feature.EditableFeatureAttributeDescriptor; |
27 |
import org.gvsig.fmap.dal.feature.EditableFeatureType; |
28 |
import org.gvsig.fmap.dal.feature.Feature; |
29 |
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor; |
30 |
import org.gvsig.fmap.dal.feature.FeatureReference; |
31 |
import org.gvsig.fmap.dal.feature.FeatureSet.DisposableFeatureSetIterable; |
32 |
import org.gvsig.fmap.dal.feature.FeatureStore; |
33 |
import static org.gvsig.fmap.dal.feature.FeatureStore.MODE_PASS_THROUGH; |
34 |
import org.gvsig.fmap.dal.feature.FeatureType; |
35 |
import org.gvsig.fmap.dal.store.jdbc.JDBCNewStoreParameters; |
36 |
import org.gvsig.fmap.dal.store.jdbc.JDBCServerExplorerParameters; |
37 |
import org.gvsig.fmap.dal.store.jdbc.JDBCStoreParameters; |
38 |
import org.gvsig.fmap.dal.store.jdbc2.JDBCServerExplorer; |
39 |
import org.gvsig.json.Json; |
40 |
import org.gvsig.tools.ToolsLocator; |
41 |
import org.gvsig.tools.dataTypes.DataTypes; |
42 |
import org.gvsig.tools.dispose.DisposableIterable; |
43 |
import org.gvsig.tools.dispose.DisposeUtils; |
44 |
import org.gvsig.tools.logger.FilteredLogger; |
45 |
import org.gvsig.tools.task.SimpleTaskStatus; |
46 |
import org.gvsig.tools.util.ContainerUtils; |
47 |
import org.gvsig.tools.util.GetItemWithSizeAndIterator64; |
48 |
import org.gvsig.tools.util.HasAFile; |
49 |
import org.gvsig.vcsgis.lib.DisposableIterableAdapter; |
50 |
import org.gvsig.vcsgis.lib.VCSGisChange; |
51 |
import org.gvsig.vcsgis.lib.VCSGisCodeGenerator; |
52 |
import org.gvsig.vcsgis.lib.VCSGisEntity; |
53 |
import static org.gvsig.vcsgis.lib.VCSGisManager.DEFAULT_DATA_TABLE; |
54 |
import static org.gvsig.vcsgis.lib.VCSGisManager.ERR_CANT_ADD_CHANGE; |
55 |
import static org.gvsig.vcsgis.lib.VCSGisManager.ERR_CANT_COMMIT; |
56 |
import static org.gvsig.vcsgis.lib.VCSGisManager.ERR_CANT_INSERT_CHANGE; |
57 |
import static org.gvsig.vcsgis.lib.VCSGisManager.ERR_CANT_INSERT_FEATURES; |
58 |
import static org.gvsig.vcsgis.lib.VCSGisManager.ERR_CANT_OPEN_CHANGES; |
59 |
import static org.gvsig.vcsgis.lib.VCSGisManager.ERR_CANT_OPEN_ENTITIES; |
60 |
import static org.gvsig.vcsgis.lib.VCSGisManager.ERR_CANT_OPEN_STORE; |
61 |
import static org.gvsig.vcsgis.lib.VCSGisManager.ERR_CANT_PREPARE_UPDATE; |
62 |
import static org.gvsig.vcsgis.lib.VCSGisManager.ERR_CANT_RETRIEVE_SOURCE_FEATURES; |
63 |
import static org.gvsig.vcsgis.lib.VCSGisManager.ERR_CANT_UPDATE; |
64 |
import static org.gvsig.vcsgis.lib.VCSGisManager.ERR_CANT_UPDATE_CLEAN; |
65 |
import static org.gvsig.vcsgis.lib.VCSGisManager.ERR_CANT_UPDATE_ENTITIES; |
66 |
import static org.gvsig.vcsgis.lib.VCSGisManager.ERR_ENTITY_ALREADY_EXISTS; |
67 |
import static org.gvsig.vcsgis.lib.VCSGisManager.ERR_ENTITY_NOT_EXISTS; |
68 |
import static org.gvsig.vcsgis.lib.VCSGisManager.ERR_ENTITY_NOT_HAS_VCSGISCODE; |
69 |
import static org.gvsig.vcsgis.lib.VCSGisManager.ERR_NO_ERROR; |
70 |
import static org.gvsig.vcsgis.lib.VCSGisManager.ERR_OK; |
71 |
import static org.gvsig.vcsgis.lib.VCSGisManager.ERR_STORE_NOT_IN_VERSION_CONTROL; |
72 |
import static org.gvsig.vcsgis.lib.VCSGisManager.ERR_UPDATE_NEED_MERGE; |
73 |
import static org.gvsig.vcsgis.lib.VCSGisManager.FEATURECODE_FIELD_NAME; |
74 |
import static org.gvsig.vcsgis.lib.VCSGisManager.OP_ADD_ENTITY; |
75 |
import static org.gvsig.vcsgis.lib.VCSGisManager.OP_DELETE; |
76 |
import static org.gvsig.vcsgis.lib.VCSGisManager.OP_INSERT; |
77 |
import static org.gvsig.vcsgis.lib.VCSGisManager.OP_UPDATE; |
78 |
import static org.gvsig.vcsgis.lib.VCSGisManager.STATE_MODIFIED; |
79 |
import static org.gvsig.vcsgis.lib.VCSGisManager.STATE_NEW; |
80 |
import static org.gvsig.vcsgis.lib.VCSGisManager.STATE_OUTDATED; |
81 |
import static org.gvsig.vcsgis.lib.VCSGisManager.STATE_OUTDATED_AND_MODIFIED; |
82 |
import static org.gvsig.vcsgis.lib.VCSGisManager.STATE_UNMODIFIED; |
83 |
import static org.gvsig.vcsgis.lib.VCSGisManagerImpl.INTERNAL_TABLES; |
84 |
import org.gvsig.vcsgis.lib.VCSGisRevision; |
85 |
import org.gvsig.vcsgis.lib.VCSGisRuntimeException; |
86 |
import org.gvsig.vcsgis.lib.VCSGisUtils; |
87 |
import org.gvsig.vcsgis.lib.repository.VCSGisRepository; |
88 |
import org.gvsig.vcsgis.lib.repository.VCSGisRepositoryChange; |
89 |
import org.gvsig.vcsgis.lib.repository.VCSGisRepositoryData; |
90 |
import org.gvsig.vcsgis.lib.repository.localdb.VCSGisRepositoryLocaldb; |
91 |
import org.gvsig.vcsgis.lib.repository.localdb.tables.EntitiesRepoTable; |
92 |
import org.gvsig.vcsgis.lib.repository.requests.VCSGisCheckoutRequest; |
93 |
import org.gvsig.vcsgis.lib.repository.requests.VCSGisCommitRequest; |
94 |
import org.gvsig.vcsgis.lib.repository.requests.VCSGisEntitiesRequest; |
95 |
import org.gvsig.vcsgis.lib.repository.requests.VCSGisLogRequest; |
96 |
import org.gvsig.vcsgis.lib.repository.requests.VCSGisUpdateRequest; |
97 |
import org.gvsig.vcsgis.lib.workspace.tables.EntitiesTable; |
98 |
import org.gvsig.vcsgis.lib.workspace.tables.EntitiesTable.EntityRow; |
99 |
import org.gvsig.vcsgis.lib.workspace.tables.LocalRevisionsTable; |
100 |
import org.gvsig.vcsgis.lib.workspace.tables.LocalRevisionsTable.LocalRevisionRow; |
101 |
import org.gvsig.vcsgis.lib.workspace.tables.RemoteChangesTable; |
102 |
import static org.gvsig.vcsgis.lib.workspace.tables.RemoteChangesTable.COD_ENTITY; |
103 |
import org.gvsig.vcsgis.lib.workspace.tables.RemoteChangesTable.RemoteChangeRow; |
104 |
import org.gvsig.vcsgis.lib.workspace.tables.VarsTable; |
105 |
import org.gvsig.vcsgis.lib.workspace.tables.WorkspaceChangesTable; |
106 |
import org.gvsig.vcsgis.lib.workspace.tables.WorkspaceChangesTable.WorkspaceChangeRow; |
107 |
import org.slf4j.Logger; |
108 |
import org.slf4j.LoggerFactory; |
109 |
|
110 |
/**
|
111 |
*
|
112 |
* @author gvSIG Team
|
113 |
*/
|
114 |
@SuppressWarnings({"UseSpecificCatch", "UnusedAssignment"}) |
115 |
public class VCSGisWorkspaceImpl implements VCSGisWorkspace { |
116 |
|
117 |
private static final Logger LOGGER = LoggerFactory.getLogger(VCSGisWorkspaceImpl.class); |
118 |
|
119 |
private final Map<String, FeatureStore> storesCache; |
120 |
private Map<String, EntityRow> workspaceEntitiesByName; |
121 |
private Map<String, EntityRow> workspaceEntitiesByCode; |
122 |
private Map<String, VCSGisEntity> repositoryEntitiesByCode; |
123 |
private Set<FeatureStore> storeIgnoreChanges; |
124 |
private JDBCServerExplorer wsexplorer;
|
125 |
private String code; |
126 |
private final VCSGisRepository repository; |
127 |
private final String label; |
128 |
private final FilteredLogger logger; |
129 |
private final VCSGisCodeGenerator codeGenerator; |
130 |
|
131 |
public VCSGisWorkspaceImpl(JDBCServerExplorer wsexplorer, VCSGisCodeGenerator codeGenerator, VCSGisRepository repository, String label) { |
132 |
this.logger = new FilteredLogger(LOGGER, "VCSGisWorkspace", 100); |
133 |
this.logger.setInterval(10000); |
134 |
this.codeGenerator = codeGenerator;
|
135 |
this.storesCache = new HashMap<>(); |
136 |
this.code = createUniqueCode();
|
137 |
this.wsexplorer = wsexplorer;
|
138 |
this.repository = repository;
|
139 |
this.label = label;
|
140 |
// LOGGER.debug("===: CREATE WORKSPACE "+ hexId(this)+ " (init label='"+this.label+"')");
|
141 |
|
142 |
} |
143 |
|
144 |
public VCSGisWorkspaceImpl(JDBCServerExplorer wsexplorer, VCSGisCodeGenerator codeGenerator) {
|
145 |
this.logger = new FilteredLogger(LOGGER, "VCSGisWorkspace", 100); |
146 |
this.logger.setInterval(10000); |
147 |
this.codeGenerator = codeGenerator;
|
148 |
this.storesCache = new HashMap<>(); |
149 |
this.wsexplorer = wsexplorer;
|
150 |
this.loadEntities();
|
151 |
|
152 |
VarsTable varsTable = new VarsTable();
|
153 |
this.code = varsTable.get(this, "WORKSPACE_CODE"); |
154 |
if (this.code == null) { |
155 |
throw new RuntimeException("Can't retrieve code from workspace '" + this.getMessageLabel() + "'"); |
156 |
} |
157 |
this.repository = (VCSGisRepository) Json.toObject(varsTable.get(this, "REPOSITORY")); |
158 |
if (this.repository == null) { |
159 |
throw new RuntimeException("Can't retrieve repository from workspace '" + this.getMessageLabel() + "'"); |
160 |
} |
161 |
this.label = varsTable.get(this, "WORKSPACE_LABEL"); |
162 |
// LOGGER.debug("===: CREATE WORKSPACE "+ hexId(this)+ " (open code='"+this.code+"', label='"+this.label+"')");
|
163 |
} |
164 |
|
165 |
public void initialize() throws Exception { |
166 |
DataManager dataManager = DALLocator.getDataManager(); |
167 |
|
168 |
// List<VCSGisEntity> rentities = this.getRepositoryEntities();
|
169 |
// if (!rentities.isEmpty()) {
|
170 |
// JDBCStoreParameters storeParams = wsexplorer.get(EntitiesTable.TABLE_NAME);
|
171 |
// FeatureStore storeEntities = (FeatureStore) dataManager.openStore(
|
172 |
// DataStore.H2SPATIAL_PROVIDER_NAME,
|
173 |
// storeParams
|
174 |
// );
|
175 |
// storeEntities.edit(FeatureStore.MODE_APPEND);
|
176 |
// for (VCSGisEntity rentity : rentities) {
|
177 |
// EntityRow entity = new EntityRow(this, storeEntities.createNewFeature());
|
178 |
// entity.copyfrom(rentity);
|
179 |
// entity.setLocalRevisionCode(null);
|
180 |
// entity.insert(storeEntities);
|
181 |
// }
|
182 |
// storeEntities.finishEditing();
|
183 |
// }
|
184 |
VarsTable varsTable = new VarsTable();
|
185 |
varsTable.set(this, "WORKSPACE_CODE", code); |
186 |
varsTable.set(this, "WORKSPACE_LABEL", label); |
187 |
varsTable.set(this, "REPOSITORY", repository.toJson().toString()); |
188 |
} |
189 |
|
190 |
private String getMessageLabel() { |
191 |
return this.wsexplorer.getParameters().getUrl(); |
192 |
} |
193 |
|
194 |
@Override
|
195 |
public String getCode() { |
196 |
return this.code; |
197 |
} |
198 |
|
199 |
@Override
|
200 |
public String getLabel() { |
201 |
return this.label; |
202 |
} |
203 |
|
204 |
@Override
|
205 |
public void dispose() { |
206 |
for (Map.Entry<String, FeatureStore> entry : storesCache.entrySet()) { |
207 |
FeatureStore store = entry.getValue(); |
208 |
if (store != null) { |
209 |
DisposeUtils.disposeQuietly(store); |
210 |
} |
211 |
} |
212 |
this.storesCache.clear();
|
213 |
DisposeUtils.dispose(this.wsexplorer);
|
214 |
this.wsexplorer= null; |
215 |
this.code = null; |
216 |
} |
217 |
|
218 |
@Override
|
219 |
public JDBCServerExplorerParameters getExplorerParameters() {
|
220 |
return this.wsexplorer.getParameters(); |
221 |
} |
222 |
|
223 |
private boolean isInStoreIgnoreChanges(FeatureStore store) { |
224 |
if (this.storeIgnoreChanges == null) { |
225 |
return false; |
226 |
} |
227 |
return this.storeIgnoreChanges.contains(store); |
228 |
} |
229 |
|
230 |
private void addStoreIgnoreChanges(FeatureStore store) { |
231 |
if (this.storeIgnoreChanges == null) { |
232 |
this.storeIgnoreChanges = new HashSet<>(); |
233 |
} |
234 |
this.storeIgnoreChanges.add(store);
|
235 |
} |
236 |
|
237 |
private void removeStoreIgnoreChanges(FeatureStore store) { |
238 |
if (this.storeIgnoreChanges == null) { |
239 |
this.storeIgnoreChanges = new HashSet<>(); |
240 |
} |
241 |
this.storeIgnoreChanges.remove(store);
|
242 |
} |
243 |
|
244 |
// private boolean contains(FeatureStore store) {
|
245 |
// return this.getEntity(store) != null;
|
246 |
// }
|
247 |
//
|
248 |
private EntityRow getEntity(FeatureStore store) {
|
249 |
String s = (String) store.getProperty("VCSGIS_WORKSPACE"); |
250 |
if (s != null) { |
251 |
if (StringUtils.equalsIgnoreCase(code, s)) {
|
252 |
return this.getWorkspaceEntityByName((String) store.getProperty("VCSGIS_ENTITY")); |
253 |
} |
254 |
return null; |
255 |
} |
256 |
|
257 |
DataStoreParameters params = store.getParameters(); |
258 |
if (!DataStore.H2SPATIAL_PROVIDER_NAME.equalsIgnoreCase(params.getProviderName())) {
|
259 |
store.setProperty("VCSGIS_WORKSPACE", "#########"); |
260 |
return null; |
261 |
} |
262 |
|
263 |
File f = ((HasAFile) params).getFile();
|
264 |
if (f == null) { |
265 |
store.setProperty("VCSGIS_WORKSPACE", "#########"); |
266 |
return null; |
267 |
} |
268 |
EntityRow entity = this.getWorkspaceEntityByName(((JDBCStoreParameters) params).getTable());
|
269 |
if (entity == null) { |
270 |
store.setProperty("VCSGIS_WORKSPACE", "#########"); |
271 |
return null; |
272 |
} |
273 |
store.setProperty("VCSGIS_WORKSPACE", this.code); |
274 |
store.setProperty("VCSGIS_ENTITY", entity.getEntityName());
|
275 |
|
276 |
return entity;
|
277 |
} |
278 |
|
279 |
private void loadEntities() { |
280 |
FeatureStore store = null;
|
281 |
try {
|
282 |
Map<String, EntityRow> theEntitiesByName = new HashMap<>(); |
283 |
Map<String, EntityRow> theEntitiesByCode = new HashMap<>(); |
284 |
store = getFeatureStore(EntitiesTable.TABLE_NAME); |
285 |
for (Feature feature : store.getFeatureSet().iterable()) {
|
286 |
EntityRow entity = new EntityRow(this, feature); |
287 |
theEntitiesByName.put(entity.getEntityName(), entity); |
288 |
theEntitiesByCode.put(entity.getCode(), entity); |
289 |
LOGGER.debug("===: loadEntities: "+entity.getEntityName()+" entity code "+entity.getEntityCode()+", repo rev. "+entity.getRepositoryRevisionCode()+", local rev. "+entity.getLocalRevisionCode()); |
290 |
} |
291 |
this.workspaceEntitiesByName = theEntitiesByName;
|
292 |
this.workspaceEntitiesByCode = theEntitiesByCode;
|
293 |
} catch (Exception ex) { |
294 |
LOGGER.warn("Can't load entity information.", ex);
|
295 |
} finally {
|
296 |
DisposeUtils.disposeQuietly(store); |
297 |
} |
298 |
} |
299 |
|
300 |
@Override
|
301 |
public List<VCSGisWorkspaceEntity> getWorkspaceEntities() { |
302 |
List<VCSGisWorkspaceEntity> entities = new ArrayList<>(); |
303 |
entities.addAll(this.getEntitiesAsEntityRow());
|
304 |
return entities;
|
305 |
} |
306 |
|
307 |
private Collection<EntityRow> getEntitiesAsEntityRow() { |
308 |
if (this.workspaceEntitiesByName == null) { |
309 |
loadEntities(); |
310 |
} |
311 |
return this.workspaceEntitiesByName.values(); |
312 |
} |
313 |
|
314 |
@Override
|
315 |
public EntityRow getWorkspaceEntityByName(String name) { |
316 |
if (this.workspaceEntitiesByName == null) { |
317 |
this.loadEntities();
|
318 |
} |
319 |
return this.workspaceEntitiesByName.get(name); |
320 |
} |
321 |
|
322 |
@Override
|
323 |
public EntityRow getWorkspaceEntityByCode(String code) { |
324 |
if (this.workspaceEntitiesByCode == null) { |
325 |
this.loadEntities();
|
326 |
} |
327 |
return this.workspaceEntitiesByCode.get(code); |
328 |
} |
329 |
|
330 |
@Override
|
331 |
public EntityRow getWorkspaceEntity(String entity) { |
332 |
EntityRow wsentity = this.getWorkspaceEntityByCode(entity);
|
333 |
if( wsentity==null ) { |
334 |
wsentity = this.getWorkspaceEntityByName(entity);
|
335 |
} |
336 |
return wsentity;
|
337 |
} |
338 |
|
339 |
@Override
|
340 |
public VCSGisEntity getRepositoryEntityByCode(String entityCode) { |
341 |
if (this.repositoryEntitiesByCode == null) { |
342 |
reloadRepositoryEntities(null);
|
343 |
} |
344 |
return this.repositoryEntitiesByCode.get(entityCode); |
345 |
} |
346 |
|
347 |
@Override
|
348 |
public VCSGisEntity getRepositoryEntityByName(String entityName) { |
349 |
if (this.repositoryEntitiesByCode == null) { |
350 |
reloadRepositoryEntities(null);
|
351 |
} |
352 |
for (VCSGisEntity entity : this.repositoryEntitiesByCode.values()) { |
353 |
if( StringUtils.equalsIgnoreCase(entity.getEntityName(), entityName) ) {
|
354 |
return entity;
|
355 |
} |
356 |
} |
357 |
return null; |
358 |
} |
359 |
|
360 |
@Override
|
361 |
public VCSGisEntity getEntity(String entityName) { |
362 |
VCSGisEntity entity = this.getWorkspaceEntity(entityName);
|
363 |
if(entity == null){ |
364 |
entity = this.getRepositoryEntity(entityName);
|
365 |
} |
366 |
return entity;
|
367 |
} |
368 |
|
369 |
@Override
|
370 |
public VCSGisEntity getRepositoryEntity(String entity) { |
371 |
VCSGisEntity rentity = this.getRepositoryEntityByCode(entity);
|
372 |
if( rentity==null ) { |
373 |
rentity = this.getRepositoryEntityByName(entity);
|
374 |
} |
375 |
return rentity;
|
376 |
} |
377 |
|
378 |
public void reloadRepositoryEntities(SimpleTaskStatus status) { |
379 |
//Esto recarga el map
|
380 |
this.getRepositoryEntities(status);
|
381 |
} |
382 |
|
383 |
|
384 |
public void reloadWorkspaceEntities() { |
385 |
this.workspaceEntitiesByCode = null; |
386 |
this.workspaceEntitiesByName = null; |
387 |
} |
388 |
|
389 |
@Override
|
390 |
public void create_table(String name) { |
391 |
EntityRow entity = this.getWorkspaceEntityByName(name);
|
392 |
if (entity == null) { |
393 |
throw new IllegalArgumentException("Can't locate informacion of table '" + name + "'."); |
394 |
} |
395 |
create_table(entity); |
396 |
} |
397 |
|
398 |
@Override
|
399 |
public void create_table(VCSGisEntity entity) { |
400 |
if (entity == null) { |
401 |
throw new IllegalArgumentException("Entity is null."); |
402 |
} |
403 |
try {
|
404 |
DataManager dataManager = DALLocator.getDataManager(); |
405 |
JDBCNewStoreParameters addparams = (JDBCNewStoreParameters) this.wsexplorer.getAddParameters(entity.getEntityName());
|
406 |
addparams.setDefaultFeatureType(entity.getFeatureType()); |
407 |
this.wsexplorer.add(DataStore.H2SPATIAL_PROVIDER_NAME, addparams, true); |
408 |
|
409 |
} catch (Exception ex) { |
410 |
throw new RuntimeException("Can't create table '" + entity.getEntityName() + "'.", ex); |
411 |
} |
412 |
|
413 |
} |
414 |
|
415 |
@Override
|
416 |
public FeatureStore getFeatureStore(String tableName) { |
417 |
EntityRow entity = null;
|
418 |
if( !INTERNAL_TABLES.contains(tableName) ) {
|
419 |
entity = this.getWorkspaceEntityByName(tableName);
|
420 |
if (entity == null) { |
421 |
return null; |
422 |
} |
423 |
return getFeatureStore(entity);
|
424 |
} |
425 |
FeatureStore store = this.storesCache.get(tableName);
|
426 |
if (store != null) { |
427 |
DisposeUtils.bind(store); |
428 |
return store;
|
429 |
} |
430 |
DataManager dataManager = DALLocator.getDataManager(); |
431 |
try {
|
432 |
JDBCStoreParameters params = this.wsexplorer.get(tableName);
|
433 |
store = (FeatureStore) dataManager.openStore( |
434 |
DataStore.H2SPATIAL_PROVIDER_NAME, |
435 |
params |
436 |
); |
437 |
|
438 |
this.storesCache.put(tableName, store);
|
439 |
|
440 |
DisposeUtils.bind(store); |
441 |
return store;
|
442 |
} catch (Exception ex) { |
443 |
String msg = "can't open store from '" + this.getMessageLabel() + "'."; |
444 |
throw new RuntimeException(msg, ex); |
445 |
} |
446 |
} |
447 |
|
448 |
private FeatureStore getFeatureStore(VCSGisEntity entity) {
|
449 |
FeatureStore store = this.storesCache.get(entity.getEntityName());
|
450 |
if (store != null) { |
451 |
DisposeUtils.bind(store); |
452 |
return store;
|
453 |
} |
454 |
DataManager dataManager = DALLocator.getDataManager(); |
455 |
try {
|
456 |
JDBCStoreParameters params = this.wsexplorer.get(entity.getEntityName());
|
457 |
store = (FeatureStore) dataManager.openStore( |
458 |
DataStore.H2SPATIAL_PROVIDER_NAME, |
459 |
params |
460 |
); |
461 |
|
462 |
StoreProperties.set(store, this, entity.getEntityName());
|
463 |
|
464 |
this.storesCache.put(entity.getEntityName(), store);
|
465 |
|
466 |
DisposeUtils.bind(store); |
467 |
return store;
|
468 |
} catch (Exception ex) { |
469 |
String msg = "can't open store from '" + this.getMessageLabel() + "'."; |
470 |
throw new RuntimeException(msg, ex); |
471 |
} |
472 |
} |
473 |
|
474 |
@Override
|
475 |
public String createUniqueCode() { |
476 |
return this.codeGenerator.generateCode(); |
477 |
} |
478 |
|
479 |
@Override
|
480 |
public String getErrorMessage(int errcode) { |
481 |
return VCSGisUtils.getErrorMessage(errcode);
|
482 |
} |
483 |
|
484 |
@Override
|
485 |
public int addChange(int operation, FeatureStore userStore, Feature feature) { |
486 |
String entityName = StoreProperties.getEntityName(userStore);
|
487 |
if (StringUtils.isBlank(entityName)) {
|
488 |
return ERR_STORE_NOT_IN_VERSION_CONTROL;
|
489 |
} |
490 |
if (this.isInStoreIgnoreChanges(userStore)) { |
491 |
LOGGER.debug("===: ADD_CHANGE: Skip ("+userStore.getName()+")"); |
492 |
return ERR_NO_ERROR;
|
493 |
} |
494 |
EntityRow entity = this.getWorkspaceEntityByName(entityName);
|
495 |
FeatureStore changesStore = this.getFeatureStore(WorkspaceChangesTable.TABLE_NAME);
|
496 |
try {
|
497 |
changesStore.edit(MODE_PASS_THROUGH); |
498 |
return addChange(entity, operation, changesStore, feature);
|
499 |
} catch(Exception ex) { |
500 |
LOGGER.warn("Can't add change (op "+VCSGisUtils.getOperationLabel(operation)+", "+entity.getEntityName()+")", ex); |
501 |
changesStore.cancelEditingQuietly(); |
502 |
return ERR_CANT_ADD_CHANGE;
|
503 |
} finally {
|
504 |
changesStore.finishEditingQuietly(); |
505 |
DisposeUtils.dispose(changesStore); |
506 |
} |
507 |
} |
508 |
|
509 |
private int addChange(VCSGisWorkspaceEntity entity, int operation, FeatureStore changesStore, Feature feature) { |
510 |
try {
|
511 |
WorkspaceChangeRow change = new WorkspaceChangeRow(this, changesStore.createNewFeature()); |
512 |
change.newCode(); |
513 |
change.setEntityCode(entity.getEntityCode()); |
514 |
change.setFeatureCode(feature.getString(entity.getFeatureIdFieldName())); |
515 |
change.setOperation(operation); |
516 |
change.setLabel(feature.getString(entity.getFieldForLabel())); |
517 |
change.setSelected(true);
|
518 |
change.insert(changesStore); |
519 |
return ERR_OK;
|
520 |
} catch(Exception ex) { |
521 |
LOGGER.warn("Can't add change (op "+VCSGisUtils.getOperationLabel(operation)+", "+entity.getEntityName()+")", ex); |
522 |
return ERR_CANT_ADD_CHANGE;
|
523 |
} |
524 |
} |
525 |
|
526 |
private int addDeleteChange(VCSGisWorkspaceEntity entity, FeatureStore changesStore, String featureCode, String label) { |
527 |
try {
|
528 |
WorkspaceChangeRow change = new WorkspaceChangeRow(this, changesStore.createNewFeature()); |
529 |
change.newCode(); |
530 |
change.setEntityCode(entity.getEntityCode()); |
531 |
change.setFeatureCode(featureCode); |
532 |
change.setOperation(OP_DELETE); |
533 |
change.setLabel(label); |
534 |
change.setSelected(true);
|
535 |
change.insert(changesStore); |
536 |
return ERR_OK;
|
537 |
} catch(Exception ex) { |
538 |
LOGGER.warn("Can't add delete change ("+entity.getEntityName()+")", ex); |
539 |
return ERR_CANT_ADD_CHANGE;
|
540 |
} |
541 |
} |
542 |
|
543 |
@Override
|
544 |
public int addEntity(FeatureType featureType, String name, String description, String fieldForLabel) { |
545 |
return this.addEntity(featureType, name, description, fieldForLabel, null); |
546 |
} |
547 |
|
548 |
|
549 |
@Override
|
550 |
public int addEntity(FeatureType featureType, String name, String description, String fieldForLabel, String pkName) { |
551 |
FeatureStore store = null;
|
552 |
int err = ERR_NO_ERROR;
|
553 |
try {
|
554 |
LOGGER.debug("===: ADD_ENTITY "+this.getCode()+", '"+this.getLabel()+"', "+name); |
555 |
EditableFeatureType ft = featureType.getCopy().getEditable(); |
556 |
|
557 |
for (FeatureAttributeDescriptor attr : ft.getPrimaryKey()) {
|
558 |
EditableFeatureAttributeDescriptor editAttr = (EditableFeatureAttributeDescriptor)attr; |
559 |
editAttr.setIsPrimaryKey(false);
|
560 |
editAttr.setAllowNull(false);
|
561 |
editAttr.setIsIndexed(true);
|
562 |
editAttr.setAllowIndexDuplicateds(false);
|
563 |
} |
564 |
|
565 |
EditableFeatureAttributeDescriptor attr = (EditableFeatureAttributeDescriptor)ft.getAttributeDescriptor(FEATURECODE_FIELD_NAME); |
566 |
if (attr == null) { |
567 |
err = ERR_ENTITY_NOT_HAS_VCSGISCODE; |
568 |
ft.add(FEATURECODE_FIELD_NAME, DataTypes.STRING) |
569 |
.setSize(40)
|
570 |
.setIsPrimaryKey(true)
|
571 |
.setIsIndexed(true)
|
572 |
.setAllowIndexDuplicateds(false)
|
573 |
.setLabel("VCSGIS Code");
|
574 |
ft.setHasOID(false);
|
575 |
} else {
|
576 |
if(!attr.isPrimaryKey()){
|
577 |
attr.setIsPrimaryKey(true);
|
578 |
ft.setHasOID(false);
|
579 |
} |
580 |
} |
581 |
|
582 |
featureType = ft.getNotEditableCopy(); |
583 |
if (featureType.getAttributeDescriptor(fieldForLabel) == null) { |
584 |
FeatureAttributeDescriptor[] pk = featureType.getPrimaryKey();
|
585 |
if( pk == null || pk.length<1 ) { |
586 |
fieldForLabel = featureType.getAttributeName(0);
|
587 |
} else {
|
588 |
fieldForLabel = pk[0].getName();
|
589 |
} |
590 |
} |
591 |
|
592 |
err = ERR_CANT_OPEN_ENTITIES; |
593 |
EntityRow entity = new EntityRow(this); |
594 |
entity.setEntityName(name); |
595 |
entity.setDataTableName(DEFAULT_DATA_TABLE); |
596 |
entity.setFeatureIdFieldName(FEATURECODE_FIELD_NAME); |
597 |
entity.setGeometryFieldName(featureType.getDefaultGeometryAttributeName()); |
598 |
entity.setDescription(description); |
599 |
entity.setFieldForLabel(fieldForLabel); |
600 |
entity.setFeatureTypeAsJson(featureType.toJsonBuilder().toString()); |
601 |
entity.setLocalRevisionCode(null);
|
602 |
entity.setRepositoryRevisionCode(null);
|
603 |
entity.setState(STATE_NEW); |
604 |
entity.insert(); |
605 |
|
606 |
this.reloadWorkspaceEntities();
|
607 |
err = ERR_CANT_INSERT_CHANGE; |
608 |
|
609 |
entity = this.getWorkspaceEntityByName(name);
|
610 |
WorkspaceChangeRow change = new WorkspaceChangeRow(this); |
611 |
change.setEntityCode(entity.getCode()); |
612 |
change.setFeatureCode(null);
|
613 |
change.setOperation(OP_ADD_ENTITY); |
614 |
change.setSelected(true);
|
615 |
change.insert(); |
616 |
|
617 |
this.create_table(entity);
|
618 |
|
619 |
} catch (VCSGisRuntimeException ex) {
|
620 |
LOGGER.warn("can't add entity '" + name + "'.", ex); |
621 |
if (store != null) { |
622 |
store.cancelEditingQuietly(); |
623 |
} |
624 |
return ex.getErrnum();
|
625 |
} catch (Exception ex) { |
626 |
LOGGER.warn("can't add entity '" + name + "'.", ex); |
627 |
if (store != null) { |
628 |
store.cancelEditingQuietly(); |
629 |
} |
630 |
return err;
|
631 |
} finally {
|
632 |
DisposeUtils.disposeQuietly(store); |
633 |
} |
634 |
return ERR_NO_ERROR;
|
635 |
} |
636 |
|
637 |
|
638 |
@Override
|
639 |
public int addChanges(FeatureStore store, Iterator<Feature> insertedsFeatures, Iterator<Feature> updatedsFeatures, Iterator<FeatureReference> deletedsFeatures) { |
640 |
String entityName = StoreProperties.getEntityName(store);
|
641 |
if (StringUtils.isBlank(entityName)) {
|
642 |
return ERR_STORE_NOT_IN_VERSION_CONTROL;
|
643 |
} |
644 |
if (this.isInStoreIgnoreChanges(store)) { |
645 |
LOGGER.debug("===: ADD_CHANGE: Skip ("+store.getName()+")"); |
646 |
return ERR_NO_ERROR;
|
647 |
} |
648 |
EntityRow entity = this.getWorkspaceEntityByName(entityName);
|
649 |
if (entity == null) { |
650 |
return ERR_STORE_NOT_IN_VERSION_CONTROL;
|
651 |
} |
652 |
WorkspaceChangesTable changesTable = new WorkspaceChangesTable();
|
653 |
FeatureStore changes_store = null;
|
654 |
int err = ERR_CANT_OPEN_CHANGES;
|
655 |
try {
|
656 |
changes_store = this.getFeatureStore(WorkspaceChangesTable.TABLE_NAME);
|
657 |
err = ERR_CANT_INSERT_CHANGE; |
658 |
changes_store.edit(FeatureStore.MODE_PASS_THROUGH); |
659 |
if (insertedsFeatures != null) { |
660 |
while (insertedsFeatures.hasNext()) {
|
661 |
Feature f = insertedsFeatures.next(); |
662 |
if (f == null) { |
663 |
continue;
|
664 |
} |
665 |
WorkspaceChangeRow change = new WorkspaceChangeRow(this); |
666 |
change.setEntityCode(entity.getCode()); |
667 |
change.setFeatureCode(f.getString(entity.getFeatureIdFieldName())); |
668 |
change.setOperation(OP_INSERT); |
669 |
change.setLabel(f.getString(entity.getFieldForLabel())); |
670 |
change.setSelected(true);
|
671 |
change.insert(changes_store); |
672 |
} |
673 |
} |
674 |
if (updatedsFeatures != null) { |
675 |
while (updatedsFeatures.hasNext()) {
|
676 |
Feature f = updatedsFeatures.next(); |
677 |
if (f == null) { |
678 |
continue;
|
679 |
} |
680 |
WorkspaceChangeRow change = new WorkspaceChangeRow(this); |
681 |
String featureCode = f.getString(entity.getFeatureIdFieldName());
|
682 |
WorkspaceChangeRow previousChange = changesTable.find(this, changes_store, entity.getCode(), featureCode);
|
683 |
if(previousChange == null) { |
684 |
change.setEntityCode(entity.getCode()); |
685 |
change.setFeatureCode(f.getString(entity.getFeatureIdFieldName())); |
686 |
change.setOperation(OP_UPDATE); |
687 |
change.setLabel(f.getString(entity.getFieldForLabel())); |
688 |
change.setSelected(true);
|
689 |
change.insert(changes_store); |
690 |
} |
691 |
} |
692 |
} |
693 |
if (deletedsFeatures != null) { |
694 |
while (deletedsFeatures.hasNext()) {
|
695 |
FeatureReference fr = deletedsFeatures.next(); |
696 |
if (fr == null) { |
697 |
continue;
|
698 |
} |
699 |
Feature f = fr.getFeatureQuietly(); |
700 |
if (f == null) { |
701 |
continue;
|
702 |
} |
703 |
WorkspaceChangeRow change = new WorkspaceChangeRow(this); |
704 |
String featureCode = f.getString(entity.getFeatureIdFieldName());
|
705 |
WorkspaceChangeRow previousChange = changesTable.find(this, changes_store, entity.getCode(), featureCode);
|
706 |
if(previousChange == null) { |
707 |
change.setEntityCode(entity.getCode()); |
708 |
change.setFeatureCode(f.getString(entity.getFeatureIdFieldName())); |
709 |
change.setOperation(OP_DELETE); |
710 |
change.setLabel(f.getString(entity.getFieldForLabel())); |
711 |
change.setSelected(true);
|
712 |
change.insert(changes_store); |
713 |
} else {
|
714 |
switch(previousChange.getOperation()){
|
715 |
case OP_INSERT:
|
716 |
previousChange.delete(changes_store); |
717 |
break;
|
718 |
case OP_DELETE:
|
719 |
LOGGER.warn("Try delete feature already deleted (.'"+previousChange.getRelatedFeature().toJson().toString()+"'"); |
720 |
break;
|
721 |
case OP_UPDATE:
|
722 |
previousChange.setOperation(OP_DELETE); |
723 |
previousChange.setSelected(true);
|
724 |
previousChange.update(); |
725 |
break;
|
726 |
} |
727 |
} |
728 |
} |
729 |
} |
730 |
changes_store.finishEditing(); |
731 |
err = ERR_NO_ERROR; |
732 |
} catch (Exception ex) { |
733 |
this.logger.warn("Can't add changes.", ex); |
734 |
if (changes_store != null) { |
735 |
changes_store.cancelEditingQuietly(); |
736 |
} |
737 |
} finally {
|
738 |
DisposeUtils.disposeQuietly(changes_store); |
739 |
} |
740 |
return err;
|
741 |
} |
742 |
|
743 |
@Override
|
744 |
public int add(String name, FeatureStore source, String fieldForLabel) { |
745 |
return this.add(name, source, fieldForLabel, null); |
746 |
} |
747 |
|
748 |
@Override
|
749 |
public int add(String name, FeatureStore source, String fieldForLabel, String pkName) { |
750 |
FeatureStore target = null;
|
751 |
DisposableFeatureSetIterable features = null;
|
752 |
int errcode = ERR_NO_ERROR;
|
753 |
try {
|
754 |
LOGGER.debug("===: ADD "+this.getCode()+", '"+this.getLabel()+"', "+name); |
755 |
EntityRow entity = this.getWorkspaceEntityByName(name);
|
756 |
if (entity != null) { |
757 |
return ERR_ENTITY_ALREADY_EXISTS;
|
758 |
} |
759 |
FeatureType ft = source.getDefaultFeatureTypeQuietly(); |
760 |
errcode = this.addEntity(ft, name, null, fieldForLabel, pkName); |
761 |
if (errcode != ERR_NO_ERROR) {
|
762 |
return errcode;
|
763 |
} |
764 |
errcode = ERR_CANT_OPEN_STORE; |
765 |
target = this.getFeatureStore(name);
|
766 |
errcode = ERR_CANT_RETRIEVE_SOURCE_FEATURES; |
767 |
features = source.getFeatureSet().iterable(); |
768 |
errcode = ERR_CANT_INSERT_FEATURES; |
769 |
target.edit(FeatureStore.MODE_APPEND); |
770 |
for (Feature feature : features) {
|
771 |
EditableFeature f = target.createNewFeature(feature); |
772 |
target.insert(f); |
773 |
} |
774 |
target.finishEditing(); |
775 |
return ERR_NO_ERROR;
|
776 |
} catch (Exception ex) { |
777 |
LOGGER.warn("Can't add features to '" + name + "' in '" + this.getMessageLabel() + "'.", ex); |
778 |
return errcode;
|
779 |
} finally {
|
780 |
DisposeUtils.disposeQuietly(features); |
781 |
DisposeUtils.disposeQuietly(target); |
782 |
} |
783 |
} |
784 |
|
785 |
@Override
|
786 |
public VCSGisWorkspaceChanges<VCSGisWorkspaceChange> getLocalChanges() {
|
787 |
WorkspaceChangesTable changesTable = new WorkspaceChangesTable();
|
788 |
ChangesImpl changes = new ChangesImpl<WorkspaceChangeRow>(changesTable.getByEntityCode(this,null), WorkspaceChangesTable.SELECTED) { |
789 |
@Override
|
790 |
protected WorkspaceChangeRow createChange(Feature f) {
|
791 |
return new WorkspaceChangeRow(VCSGisWorkspaceImpl.this, f); |
792 |
} |
793 |
|
794 |
@Override
|
795 |
protected void updateChange(FeatureStore store, WorkspaceChangeRow change) { |
796 |
change.update(store); |
797 |
} |
798 |
|
799 |
}; |
800 |
return changes;
|
801 |
} |
802 |
|
803 |
@Override
|
804 |
public VCSGisWorkspaceChanges<VCSGisWorkspaceChange> getLocalChangesByEntityName(String entityName) { |
805 |
EntityRow entity = this.getWorkspaceEntityByName(entityName);
|
806 |
return getLocalChangesByEntityCode(entity.getEntityCode());
|
807 |
} |
808 |
|
809 |
@Override
|
810 |
public VCSGisWorkspaceChanges<VCSGisWorkspaceChange> getLocalChangesByEntityCode(String entityCode) { |
811 |
WorkspaceChangesTable changesTable = new WorkspaceChangesTable();
|
812 |
ChangesImpl changes = new ChangesImpl<WorkspaceChangeRow>(changesTable.getByEntityCode(this,entityCode),WorkspaceChangesTable.SELECTED) { |
813 |
@Override
|
814 |
protected WorkspaceChangeRow createChange(Feature f) {
|
815 |
return new WorkspaceChangeRow(VCSGisWorkspaceImpl.this, f); |
816 |
} |
817 |
|
818 |
@Override
|
819 |
protected void updateChange(FeatureStore store, WorkspaceChangeRow change) { |
820 |
change.update(store); |
821 |
} |
822 |
|
823 |
}; |
824 |
return changes;
|
825 |
} |
826 |
|
827 |
@Override
|
828 |
public VCSGisRepository getRepository() {
|
829 |
return repository;
|
830 |
} |
831 |
|
832 |
@Override
|
833 |
public List<VCSGisEntity> getEntitiesOfRemoteChanges() { |
834 |
ArrayList<VCSGisEntity> res = new ArrayList<>(); |
835 |
RemoteChangesTable changesTable = new RemoteChangesTable();
|
836 |
DisposableFeatureSetIterable features = changesTable.getGroupedByEntity(this);
|
837 |
EntitiesRepoTable entitiesRepoTable = new EntitiesRepoTable();
|
838 |
for (Feature feature : features) {
|
839 |
VCSGisEntity entity = entitiesRepoTable.getByEntityCode((VCSGisRepositoryLocaldb) this.getRepository(), feature.getString(RemoteChangesTable.COD_ENTITY));
|
840 |
res.add(entity); |
841 |
} |
842 |
DisposeUtils.disposeQuietly(features); |
843 |
return res;
|
844 |
} |
845 |
|
846 |
@Override
|
847 |
public VCSGisWorkspaceChanges<VCSGisRepositoryChange> getRemoteChanges() {
|
848 |
return getRemoteChangesByEntity(null); |
849 |
} |
850 |
|
851 |
@Override
|
852 |
public VCSGisWorkspaceChanges<VCSGisRepositoryChange> getRemoteChangesByEntity(String entityName) { |
853 |
String entityCode;
|
854 |
if(StringUtils.isBlank(entityName)){
|
855 |
entityCode = null;
|
856 |
} else {
|
857 |
VCSGisEntity entity = this.getWorkspaceEntity(entityName);
|
858 |
if(entity == null){ |
859 |
entity = this.getRepositoryEntity(entityName);
|
860 |
if(entity == null){ |
861 |
return null; |
862 |
} |
863 |
} |
864 |
entityCode = entity.getEntityCode(); |
865 |
} |
866 |
RemoteChangesTable changesTable = new RemoteChangesTable();
|
867 |
ChangesImpl changes = new ChangesImpl<RemoteChangeRow>(changesTable.getByEntityCode(this,entityCode),RemoteChangesTable.SELECTED) { |
868 |
@Override
|
869 |
protected RemoteChangeRow createChange(Feature f) {
|
870 |
return new RemoteChangeRow(VCSGisWorkspaceImpl.this, f); |
871 |
} |
872 |
|
873 |
@Override
|
874 |
protected void updateChange(FeatureStore store, RemoteChangeRow change) { |
875 |
change.update(store); |
876 |
} |
877 |
|
878 |
}; |
879 |
return changes;
|
880 |
} |
881 |
|
882 |
private Timestamp now() { |
883 |
return Timestamp.from(LocalDateTime.now().toInstant(ZoneOffset.UTC)); |
884 |
} |
885 |
|
886 |
public boolean prepareCommitRequest(VCSGisCommitRequest request, Timestamp efectivedate, String comment, SimpleTaskStatus status) { |
887 |
if( status==null ) { |
888 |
status = ToolsLocator.getTaskStatusManager().createDefaultSimpleTaskStatus("Prepare commit request");
|
889 |
status.setAutoremove(true);
|
890 |
status.add(); |
891 |
} |
892 |
request.setEfectiveDate(efectivedate); |
893 |
request.setComment(comment); |
894 |
WorkspaceChangesTable changesTable = new WorkspaceChangesTable();
|
895 |
|
896 |
LOGGER.debug("===: COMMIT: Adding changed local entities");
|
897 |
status.message("Searching changed entities");
|
898 |
// adicionamos las entidades que vamos a actualizar con las revisiones que tenemos.
|
899 |
DisposableFeatureSetIterable changesGroupedByEntity = changesTable.getGroupedByEntity(this);
|
900 |
for (Feature fchange : changesGroupedByEntity) {
|
901 |
WorkspaceChangeRow change = new WorkspaceChangeRow(this, fchange); |
902 |
VCSGisEntity localEntity = change.getEntity(); |
903 |
LOGGER.debug("===: COMMIT: add used entity = "+fchange.toJson().toString().replace('\n', ' ')); |
904 |
request.add(request.createEntity(localEntity)); |
905 |
} |
906 |
changesGroupedByEntity.dispose(); |
907 |
|
908 |
LOGGER.debug("===: COMMIT: Mark new local entities");
|
909 |
status.message("Searching new entities");
|
910 |
// Marcamos como nuevas las entidades que se han dado de alta.
|
911 |
DisposableFeatureSetIterable changesOfAddEntities = changesTable.getByOperation(this, OP_ADD_ENTITY);
|
912 |
for (Feature fchange : changesOfAddEntities) {
|
913 |
WorkspaceChangeRow change = new WorkspaceChangeRow(this, fchange); |
914 |
request.markAsNew(change.getEntity()); |
915 |
} |
916 |
changesOfAddEntities.dispose(); |
917 |
|
918 |
LOGGER.debug("===: COMMIT: Adding data");
|
919 |
status.message("Searching changed data");
|
920 |
// adicionamos los datos
|
921 |
boolean useSeleccion = true; |
922 |
DisposableFeatureSetIterable changes = changesTable.getSelectedsWithoutAddEntity(this);
|
923 |
if (changes == null) { |
924 |
changes = changesTable.getAll(this);
|
925 |
useSeleccion = false;
|
926 |
} |
927 |
request.add(new DisposableIterableAdapter(
|
928 |
changes, |
929 |
new DisposableIterableAdapter.ItemConverter<Feature, VCSGisChange>() {
|
930 |
@Override
|
931 |
public VCSGisChange convert(Feature f) {
|
932 |
return new WorkspaceChangeRow(VCSGisWorkspaceImpl.this, f); |
933 |
} |
934 |
} |
935 |
) |
936 |
); |
937 |
return useSeleccion;
|
938 |
} |
939 |
|
940 |
@Override
|
941 |
public int commit() { |
942 |
return commit(now(),null, null); |
943 |
} |
944 |
|
945 |
@Override
|
946 |
@SuppressWarnings("Convert2Lambda") |
947 |
public int commit(Timestamp efectivedate, String comment, SimpleTaskStatus status) { |
948 |
VCSGisCommitRequest request = null;
|
949 |
if( status==null ) { |
950 |
status = ToolsLocator.getTaskStatusManager().createDefaultSimpleTaskStatus("Commit");
|
951 |
status.setAutoremove(true);
|
952 |
status.add(); |
953 |
} |
954 |
try {
|
955 |
LOGGER.debug("===: COMMIT "+this.getCode()+", "+this.getLabel()); |
956 |
EntitiesTable entitiesTable = new EntitiesTable();
|
957 |
WorkspaceChangesTable changesTable = new WorkspaceChangesTable();
|
958 |
|
959 |
status.message("Preparing commit");
|
960 |
reloadRepositoryEntities(status); |
961 |
request = this.repository.createCommitRequest();
|
962 |
|
963 |
boolean useSeleccion = this.prepareCommitRequest(request, efectivedate, comment, status); |
964 |
|
965 |
LOGGER.debug("===: COMMIT: Do execute request");
|
966 |
status.message("Executing commit request");
|
967 |
if( request.execute()!=ERR_NO_ERROR ) {
|
968 |
status.message("Can't commit changes (error "+request.getLastErrorCode()+")"); |
969 |
status.abort(); |
970 |
return request.getLastErrorCode();
|
971 |
} |
972 |
|
973 |
LOGGER.debug("===: COMMIT: update local entities table");
|
974 |
status.message("Updating local metadata");
|
975 |
FeatureStore store = null;
|
976 |
try {
|
977 |
store = this.getFeatureStore(EntitiesTable.TABLE_NAME);
|
978 |
store.edit(FeatureStore.MODE_FULLEDIT); |
979 |
for (VCSGisEntity rentity : request.getChangedLocalEntities()) {
|
980 |
EntityRow entityRow = entitiesTable.getByEntityName(this, rentity.getEntityName());
|
981 |
if (entityRow != null) { |
982 |
entityRow.copyfrom(rentity); |
983 |
entityRow.setLocalRevisionCode(rentity.getRepositoryRevisionCode()); |
984 |
entityRow.update(store); |
985 |
} |
986 |
} |
987 |
store.finishEditing(); |
988 |
reloadWorkspaceEntities(); |
989 |
} finally {
|
990 |
DisposeUtils.disposeQuietly(store); |
991 |
store = null;
|
992 |
} |
993 |
|
994 |
LOGGER.debug("===: COMMIT: clean local changes");
|
995 |
status.message("Removing local list of changes");
|
996 |
if (useSeleccion) {
|
997 |
changesTable.deleteSelecteds(this);
|
998 |
} else {
|
999 |
changesTable.deleteAll(this);
|
1000 |
} |
1001 |
status.message("Commit completed");
|
1002 |
status.terminate(); |
1003 |
return ERR_NO_ERROR;
|
1004 |
} catch (Exception ex) { |
1005 |
LOGGER.warn("Can't commit changes.", ex);
|
1006 |
status.message("Can't commit changes");
|
1007 |
status.abort(); |
1008 |
return ERR_CANT_COMMIT;
|
1009 |
} finally {
|
1010 |
DisposeUtils.disposeQuietly(request); |
1011 |
} |
1012 |
} |
1013 |
|
1014 |
@Override
|
1015 |
public int checkout(String tableName) { |
1016 |
return checkout(tableName, null); |
1017 |
} |
1018 |
|
1019 |
@Override
|
1020 |
public int checkout(String tableName, SimpleTaskStatus status) { |
1021 |
FeatureStore target = null;
|
1022 |
int errcode = ERR_OK;
|
1023 |
VCSGisCheckoutRequest request = null;
|
1024 |
if( status==null ) { |
1025 |
status = ToolsLocator.getTaskStatusManager().createDefaultSimpleTaskStatus("Checkout");
|
1026 |
status.setAutoremove(true);
|
1027 |
status.add(); |
1028 |
} |
1029 |
try {
|
1030 |
LOGGER.debug("===: CHECKOUT "+this.getCode()+", '"+this.getLabel()+"', "+tableName); |
1031 |
status.message("Preparing checkout");
|
1032 |
EntityRow lentity = this.getWorkspaceEntityByName(tableName);
|
1033 |
if(lentity != null){ |
1034 |
status.message("Table "+tableName+" already exists"); |
1035 |
status.abort(); |
1036 |
return ERR_ENTITY_ALREADY_EXISTS;
|
1037 |
} |
1038 |
reloadRepositoryEntities(status); |
1039 |
request = this.repository.createCheckoutRequest(tableName);
|
1040 |
request.setEfectiveDate((Timestamp)null); |
1041 |
request.setRevisionCode(null);
|
1042 |
|
1043 |
status.message("Executing checkout request for "+tableName);
|
1044 |
if( request.execute()!=ERR_OK ) {
|
1045 |
status.message("Can't checkout "+tableName+" (error "+request.getLastErrorCode()+")"); |
1046 |
status.abort(); |
1047 |
return request.getLastErrorCode();
|
1048 |
} |
1049 |
status.message("Updating "+tableName+" metadata"); |
1050 |
VCSGisEntity rentity = request.getEntity(); |
1051 |
lentity = new EntityRow(this); |
1052 |
rentity.copyto(lentity); |
1053 |
lentity.insert(); |
1054 |
LOGGER.debug("===: CHECKOUT "+this.getCode()+", '"+this.getLabel()+"', "+tableName+", rev."+rentity.getRepositoryRevisionCode()); |
1055 |
|
1056 |
this.reloadWorkspaceEntities();
|
1057 |
|
1058 |
status.message("Creating table "+tableName);
|
1059 |
this.create_table(lentity);
|
1060 |
|
1061 |
status.message("Adding features in "+tableName);
|
1062 |
errcode = ERR_CANT_OPEN_STORE; |
1063 |
target = this.getFeatureStore(tableName);
|
1064 |
this.addStoreIgnoreChanges(target);
|
1065 |
DisposableIterable<VCSGisRepositoryData> data = request.getData(); |
1066 |
long sz = ContainerUtils.size64(data);
|
1067 |
status.setRangeOfValues(0, sz);
|
1068 |
status.setCurValue(0);
|
1069 |
errcode = ERR_CANT_INSERT_FEATURES; |
1070 |
target.edit(FeatureStore.MODE_APPEND); |
1071 |
for (VCSGisRepositoryData d : data) {
|
1072 |
EditableFeature f = target.createNewFeature(d.getDataAsJson()); |
1073 |
target.insert(f); |
1074 |
status.incrementCurrentValue(); |
1075 |
} |
1076 |
target.finishEditing(); |
1077 |
|
1078 |
status.message("Updating "+tableName+" metadata"); |
1079 |
lentity.setLocalRevisionCode(rentity.getRepositoryRevisionCode()); |
1080 |
lentity.update(); |
1081 |
this.reloadWorkspaceEntities();
|
1082 |
|
1083 |
request.dispose(); |
1084 |
|
1085 |
status.message("Checkout completed");
|
1086 |
status.terminate(); |
1087 |
return ERR_NO_ERROR;
|
1088 |
} catch (Exception ex) { |
1089 |
LOGGER.warn("Can't checkout.", ex);
|
1090 |
status.message("Can't checkout");
|
1091 |
status.abort(); |
1092 |
return errcode;
|
1093 |
} finally {
|
1094 |
DisposeUtils.disposeQuietly(request); |
1095 |
if(target != null) { |
1096 |
this.removeStoreIgnoreChanges(target);
|
1097 |
} |
1098 |
DisposeUtils.disposeQuietly(target); |
1099 |
} |
1100 |
} |
1101 |
|
1102 |
@Override
|
1103 |
public int updateEntities() { |
1104 |
return this.updateEntities(null); |
1105 |
} |
1106 |
|
1107 |
@Override
|
1108 |
public int updateEntities(SimpleTaskStatus status) { |
1109 |
LOGGER.debug("===: UPDATE_ENTITIES "+this.getCode()+", '"+this.getLabel()+"'"); |
1110 |
FeatureStore store = null;
|
1111 |
EntitiesTable entitiesTable = new EntitiesTable();
|
1112 |
if( status==null ) { |
1113 |
status = ToolsLocator.getTaskStatusManager().createDefaultSimpleTaskStatus("Update metadata tables");
|
1114 |
status.setAutoremove(true);
|
1115 |
status.add(); |
1116 |
} |
1117 |
try {
|
1118 |
status.message("Preparing update metadata tables");
|
1119 |
store = this.getFeatureStore(EntitiesTable.TABLE_NAME);
|
1120 |
store.edit(FeatureStore.MODE_PASS_THROUGH); |
1121 |
for (VCSGisEntity rentity : this.getRepositoryEntities(status)) { |
1122 |
EntityRow entityRow = entitiesTable.getByEntityName(this, rentity.getEntityName());
|
1123 |
if (entityRow != null) { |
1124 |
rentity.copyto(entityRow); |
1125 |
entityRow.update(store); |
1126 |
} |
1127 |
} |
1128 |
reloadWorkspaceEntities(); |
1129 |
store.finishEditingQuietly(); |
1130 |
status.message("Update metadata tables completed");
|
1131 |
status.terminate(); |
1132 |
return ERR_OK;
|
1133 |
} catch (Exception ex) { |
1134 |
LOGGER.warn("Can't update metadata tables.", ex);
|
1135 |
status.message("Can't update metadata tables");
|
1136 |
status.abort(); |
1137 |
return ERR_CANT_UPDATE_ENTITIES;
|
1138 |
} finally {
|
1139 |
DisposeUtils.disposeQuietly(store); |
1140 |
store = null;
|
1141 |
} |
1142 |
} |
1143 |
|
1144 |
@Override
|
1145 |
public int updatePrepare(String tableName) { |
1146 |
return updatePrepare(tableName, null); |
1147 |
} |
1148 |
|
1149 |
@Override
|
1150 |
public int updatePrepare(String tableName, SimpleTaskStatus status) { |
1151 |
LOGGER.debug("===: UPDATE_PREPARE: "+tableName+" WS "+this.getCode()+", '"+this.getLabel()+"'"); |
1152 |
if( status==null ) { |
1153 |
status = ToolsLocator.getTaskStatusManager().createDefaultSimpleTaskStatus("Update-prepare "+tableName);
|
1154 |
status.setAutoremove(true);
|
1155 |
status.add(); |
1156 |
} |
1157 |
|
1158 |
FeatureStore target = null;
|
1159 |
VCSGisUpdateRequest request = null;
|
1160 |
DisposableIterable<VCSGisRepositoryData> remoteChanges = null;
|
1161 |
WorkspaceChangesTable changesTable = new WorkspaceChangesTable();
|
1162 |
try {
|
1163 |
status.message("Preparing update-prepare");
|
1164 |
reloadRepositoryEntities(status); |
1165 |
request = this.repository.createUpdateRequest(tableName);
|
1166 |
EntityRow lentity = this.getWorkspaceEntityByName(tableName);
|
1167 |
if(lentity != null){ |
1168 |
request.setLocalRevisionCode(lentity.getLocalRevisionCode()); |
1169 |
} |
1170 |
|
1171 |
status.message("Executing update-prepare request");
|
1172 |
if( request.execute()!=ERR_OK ) {
|
1173 |
status.message("Can't update-prepare "+tableName+" (error "+request.getLastErrorCode()+")"); |
1174 |
status.abort(); |
1175 |
return request.getLastErrorCode();
|
1176 |
} |
1177 |
status.message("Updating "+tableName+" metadata"); |
1178 |
LOGGER.debug("===: UPDATE_PREPARE: "+tableName+" request code "+request.getCode()); |
1179 |
VCSGisEntity rentity = request.getEntity(); |
1180 |
if(lentity == null){ |
1181 |
lentity = new EntityRow(this); |
1182 |
lentity.copyfrom(rentity); |
1183 |
lentity.setLocalRevisionCode(null);
|
1184 |
} else {
|
1185 |
lentity.copyfrom(rentity); |
1186 |
lentity.update(); |
1187 |
} |
1188 |
this.reloadWorkspaceEntities();
|
1189 |
String entityCode = lentity.getCode();
|
1190 |
LOGGER.debug("===: UPDATE_PREPARE: "+tableName+" entity code "+entityCode+", repo rev. "+lentity.getRepositoryRevisionCode()+", local rev. "+lentity.getLocalRevisionCode()); |
1191 |
|
1192 |
status.message("Preparing remote changes container");
|
1193 |
target = this.getFeatureStore(RemoteChangesTable.TABLE_NAME);
|
1194 |
target.edit(MODE_PASS_THROUGH); |
1195 |
|
1196 |
status.message("Deleting previous temporary remote changes");
|
1197 |
LOGGER.debug("===: UPDATE_PREPARE: Delete updates table");
|
1198 |
target.delete("\""+COD_ENTITY+"\"='"+entityCode+"'"); |
1199 |
|
1200 |
remoteChanges = request.getData(); |
1201 |
long sz = ContainerUtils.size64(remoteChanges);
|
1202 |
status.setRangeOfValues(0, sz);
|
1203 |
status.setCurValue(0);
|
1204 |
|
1205 |
LOGGER.debug("===: UPDATE_PREPARE: Inserting updates");
|
1206 |
for (VCSGisRepositoryData remoteChange : remoteChanges) {
|
1207 |
RemoteChangeRow remoteChangeRow = new RemoteChangeRow(this); |
1208 |
LOGGER.debug("===: UPDATE_PREPARE: insert "+remoteChange.getFeatureRelatedCode()+", "+remoteChange.getOperation()+", "+remoteChange.getData()); |
1209 |
remoteChangeRow.setCode(remoteChange.getFeatureRelatedCode()); |
1210 |
remoteChangeRow.setData(remoteChange.getData()); |
1211 |
remoteChangeRow.setEntityCode(remoteChange.getEntityCode()); |
1212 |
remoteChangeRow.setDataCode(remoteChange.getFeatureRelatedCode()); |
1213 |
remoteChangeRow.setOperation(remoteChange.getOperation()); |
1214 |
remoteChangeRow.setRevisionCode(remoteChange.getRevisionCode()); |
1215 |
remoteChangeRow.setRevisionNumber(remoteChange.getRevisionNumber()); |
1216 |
|
1217 |
LOGGER.debug("===: UPDATE_PREPARE: row code = "+remoteChangeRow.getRelatedFeatureCode());
|
1218 |
LOGGER.debug("===: UPDATE_PREPARE: row state = "+lentity.getState()+", "+lentity.getStateLabel()); |
1219 |
LOGGER.debug("===: UPDATE_PREPARE: row operation = "+remoteChangeRow.getOperation()+", "+remoteChangeRow.getOperationLabel()); |
1220 |
switch (lentity.getState()) {
|
1221 |
case STATE_OUTDATED:
|
1222 |
case STATE_UNMODIFIED:
|
1223 |
remoteChangeRow.setSelected(true);
|
1224 |
break;
|
1225 |
case STATE_NEW:
|
1226 |
case STATE_OUTDATED_AND_MODIFIED:
|
1227 |
case STATE_MODIFIED:
|
1228 |
WorkspaceChangeRow change = changesTable.getByEntityAndDataCode(this,
|
1229 |
entityCode, |
1230 |
remoteChangeRow.getRelatedFeatureCode() |
1231 |
); |
1232 |
if( change==null ) { |
1233 |
LOGGER.debug("===: UPDATE_PREPARE: no local modificacion, update local data");
|
1234 |
// Solo actualizamos si no ha sido modificado localmente.
|
1235 |
remoteChangeRow.setSelected(true);
|
1236 |
} else {
|
1237 |
LOGGER.debug("===: UPDATE_PREPARE: not update. Local data is modified. "+change.getData().replace('\n', ' ')); |
1238 |
remoteChangeRow.setSelected(false);
|
1239 |
} |
1240 |
break;
|
1241 |
} |
1242 |
remoteChangeRow.insert(target); |
1243 |
status.incrementCurrentValue(); |
1244 |
} |
1245 |
LOGGER.debug("===: UPDATE_PREPARE: finish inserting updates");
|
1246 |
target.finishEditing(); |
1247 |
|
1248 |
status.message("Update-prepare completed");
|
1249 |
status.terminate(); |
1250 |
return ERR_OK;
|
1251 |
} catch (Exception ex) { |
1252 |
LOGGER.warn("Can't prepare update.", ex);
|
1253 |
status.message("Can't prepare update");
|
1254 |
status.abort(); |
1255 |
if( target!=null ) { |
1256 |
target.cancelEditingQuietly(); |
1257 |
} |
1258 |
return ERR_CANT_PREPARE_UPDATE;
|
1259 |
} finally {
|
1260 |
DisposeUtils.disposeQuietly(remoteChanges); |
1261 |
DisposeUtils.disposeQuietly(request); |
1262 |
DisposeUtils.disposeQuietly(target); |
1263 |
} |
1264 |
|
1265 |
} |
1266 |
|
1267 |
@Override
|
1268 |
public int updateClean(String entityCode) { |
1269 |
return updateClean(entityCode, null); |
1270 |
} |
1271 |
|
1272 |
@Override
|
1273 |
public int updateClean(String entityCode, SimpleTaskStatus status) { |
1274 |
VCSGisEntity entity = this.getEntity(entityCode);
|
1275 |
if( entity == null ) { |
1276 |
return ERR_ENTITY_NOT_EXISTS;
|
1277 |
} |
1278 |
if( status==null ) { |
1279 |
status = ToolsLocator.getTaskStatusManager().createDefaultSimpleTaskStatus( |
1280 |
"Update-clean "+entity.getEntityName()
|
1281 |
); |
1282 |
status.setAutoremove(true);
|
1283 |
status.add(); |
1284 |
} |
1285 |
try {
|
1286 |
status.message("Deleting temporary remote changes ("+entity.getEntityName()+")"); |
1287 |
RemoteChangesTable remoteChangesTable = new RemoteChangesTable();
|
1288 |
remoteChangesTable.delete(this, entityCode);
|
1289 |
status.message("Delete temporary remote changes completed");
|
1290 |
status.terminate(); |
1291 |
return ERR_OK;
|
1292 |
} catch (Exception ex) { |
1293 |
LOGGER.warn("Can't deleting temporary remote changes of "+entity.getEntityName()+".", ex); |
1294 |
status.message("Can't deleting temporary remote changes of "+entity.getEntityName()+"."); |
1295 |
status.abort(); |
1296 |
return ERR_CANT_UPDATE_CLEAN;
|
1297 |
} |
1298 |
|
1299 |
} |
1300 |
|
1301 |
@Override
|
1302 |
public int update(String tableName) { |
1303 |
return this.update(tableName, true, true, null); |
1304 |
} |
1305 |
|
1306 |
@Override
|
1307 |
public int update(String tableName, SimpleTaskStatus status) { |
1308 |
return this.update(tableName, false, false, status); |
1309 |
} |
1310 |
|
1311 |
@Override
|
1312 |
public int merge(String tableName) { |
1313 |
return this.update(tableName, false, true, null); |
1314 |
} |
1315 |
|
1316 |
@Override
|
1317 |
public int merge(String tableName, SimpleTaskStatus status) { |
1318 |
return this.update(tableName, false, true, status); |
1319 |
} |
1320 |
|
1321 |
public int update(String tableName, boolean prepare, boolean merge, SimpleTaskStatus status) { |
1322 |
int errcode = ERR_NO_ERROR;
|
1323 |
if( status==null ) { |
1324 |
status = ToolsLocator.getTaskStatusManager().createDefaultSimpleTaskStatus( |
1325 |
"Update "+tableName
|
1326 |
); |
1327 |
status.setAutoremove(true);
|
1328 |
status.add(); |
1329 |
} |
1330 |
if( prepare ) {
|
1331 |
errcode = this.updatePrepare(tableName, status);
|
1332 |
if (errcode != ERR_OK) {
|
1333 |
return errcode;
|
1334 |
} |
1335 |
} |
1336 |
LOGGER.debug("===: UPDATE "+this.getCode()+", '"+this.getLabel()+"', "+tableName); |
1337 |
RemoteChangesTable remoteChangesTable = new RemoteChangesTable();
|
1338 |
|
1339 |
EditableFeature ef; |
1340 |
FeatureStore target = null;
|
1341 |
DisposableFeatureSetIterable features = null;
|
1342 |
FeatureStore changesStore = null;
|
1343 |
try {
|
1344 |
EntityRow lentity = this.getWorkspaceEntityByName(tableName);
|
1345 |
if(lentity == null){ |
1346 |
VCSGisEntity rentity = this.getRepositoryEntityByName(tableName);
|
1347 |
lentity = new EntityRow(this); |
1348 |
lentity.copyfrom(rentity); |
1349 |
lentity.setLocalRevisionCode(null);
|
1350 |
} |
1351 |
if( !merge ){
|
1352 |
status.message("Checking the need to merge");
|
1353 |
if(remoteChangesTable.updateNeedMerge(this, lentity.getEntityCode())){ |
1354 |
status.message("Can't update without merge.");
|
1355 |
status.abort(); |
1356 |
return ERR_UPDATE_NEED_MERGE;
|
1357 |
} |
1358 |
} |
1359 |
String dataCodeFieldName = lentity.getFeatureIdFieldName();
|
1360 |
status.message("Searching remote changes ("+lentity.getEntityName()+")"); |
1361 |
|
1362 |
try {
|
1363 |
target = this.getFeatureStore(lentity);
|
1364 |
} catch (Exception e){ |
1365 |
LOGGER.warn("Can't get feature store from '"+tableName+"'", e); |
1366 |
} |
1367 |
if(target == null) { |
1368 |
this.create_table(lentity);
|
1369 |
target = this.getFeatureStore(lentity);
|
1370 |
} |
1371 |
|
1372 |
features = remoteChangesTable.getSelectedsByEntityCodeAsIterator(this,lentity.getCode());
|
1373 |
long sz = ContainerUtils.size64(features);
|
1374 |
status.setRangeOfValues(0, sz);
|
1375 |
status.setCurValue(0);
|
1376 |
|
1377 |
if(!features.isEmpty()){
|
1378 |
target.edit(MODE_PASS_THROUGH); |
1379 |
this.addStoreIgnoreChanges(target);
|
1380 |
status.message("Updating table ("+lentity.getEntityName()+")"); |
1381 |
FeatureType type = target.getDefaultFeatureTypeQuietly(); |
1382 |
|
1383 |
ExpressionEvaluatorManager expManager = ExpressionEvaluatorLocator.getManager(); |
1384 |
ExpressionBuilder builder = expManager.createExpressionBuilder(); |
1385 |
|
1386 |
for (Feature feature : features) {
|
1387 |
RemoteChangeRow remoteChangeRow = new RemoteChangeRow(this, feature); |
1388 |
switch (remoteChangeRow.getOperation()) {
|
1389 |
case OP_INSERT:
|
1390 |
LOGGER.debug("===: UPDATE: insert");
|
1391 |
ef = target.createNewFeature(remoteChangeRow.getDataAsJson()); |
1392 |
target.insert(ef); |
1393 |
break;
|
1394 |
case OP_UPDATE:
|
1395 |
LOGGER.debug("===: UPDATE: update");
|
1396 |
JsonObject dataJson = remoteChangeRow.getDataAsJson(); |
1397 |
builder.set(null);
|
1398 |
for (FeatureAttributeDescriptor attr : type.getPrimaryKey()) {
|
1399 |
builder.and( |
1400 |
builder.eq( |
1401 |
builder.column(attr.getName()), |
1402 |
builder.constant( |
1403 |
Json.toObject(dataJson.get(attr.getName())) |
1404 |
) |
1405 |
) |
1406 |
); |
1407 |
} |
1408 |
Feature f = target.findFirst(builder.toString()); |
1409 |
if(f==null){ |
1410 |
throw new NullPointerException("Can't update null feature ("+builder.toString()+")."); |
1411 |
} |
1412 |
ef = f.getEditable(); |
1413 |
// ef = target.createNewFeature(false);
|
1414 |
// ef.setUpdatable(true);
|
1415 |
ef.copyFrom(dataJson); |
1416 |
target.update(ef); |
1417 |
break;
|
1418 |
|
1419 |
case OP_DELETE:
|
1420 |
LOGGER.debug("===: UPDATE: delete");
|
1421 |
target.delete("\"" + dataCodeFieldName + "\"='" + remoteChangeRow.getRelatedFeatureCode()+ "'"); |
1422 |
break;
|
1423 |
} |
1424 |
status.incrementCurrentValue(); |
1425 |
} |
1426 |
target.finishEditing(); |
1427 |
} |
1428 |
|
1429 |
if(merge){
|
1430 |
status.message("Searching local changes to merge ("+lentity.getEntityName()+")"); |
1431 |
DisposeUtils.disposeQuietly(features); |
1432 |
features = remoteChangesTable.getNotSelectedsByEntityCodeAsIterator(this,lentity.getCode());
|
1433 |
sz = ContainerUtils.size64(features); |
1434 |
status.setRangeOfValues(0, sz);
|
1435 |
status.setCurValue(0);
|
1436 |
|
1437 |
if(!features.isEmpty()){
|
1438 |
//We edit the changesStore because we will need local changes
|
1439 |
changesStore = this.getFeatureStore(WorkspaceChangesTable.TABLE_NAME);
|
1440 |
changesStore.edit(MODE_PASS_THROUGH); |
1441 |
|
1442 |
//We edit the target store because perhaps we will need update some feature (in case OP_DELETE)
|
1443 |
target.edit(MODE_PASS_THROUGH); |
1444 |
this.addStoreIgnoreChanges(target);
|
1445 |
|
1446 |
status.message("Adding to local changes ("+lentity.getEntityName()+")"); |
1447 |
for (Feature feature : features) {
|
1448 |
RemoteChangeRow remoteChangeRow = new RemoteChangeRow(this, feature); |
1449 |
Feature f = target.findFirst("\""+lentity.getFeatureIdFieldName()+"\" = '"+remoteChangeRow.getRelatedFeatureCode()+"'"); |
1450 |
switch (remoteChangeRow.getOperation()) {
|
1451 |
case OP_INSERT:
|
1452 |
LOGGER.debug("===: UPDATE: insert");
|
1453 |
if(f==null){ |
1454 |
this.addDeleteChange(lentity, changesStore, remoteChangeRow.getRelatedFeatureCode(), null); |
1455 |
} else {
|
1456 |
this.addChange(lentity, OP_UPDATE, changesStore, f);
|
1457 |
} |
1458 |
break;
|
1459 |
|
1460 |
case OP_UPDATE:
|
1461 |
LOGGER.debug("===: UPDATE: update");
|
1462 |
if(f==null){ |
1463 |
this.addDeleteChange(lentity, changesStore, remoteChangeRow.getRelatedFeatureCode(), null); |
1464 |
} else {
|
1465 |
this.addChange(lentity, OP_UPDATE, changesStore, f);
|
1466 |
} |
1467 |
break;
|
1468 |
case OP_DELETE:
|
1469 |
LOGGER.debug("===: UPDATE: delete");
|
1470 |
if(f!=null){ |
1471 |
//TODO: delete de la f y un insert de una nueva
|
1472 |
target.delete("\"" + dataCodeFieldName + "\"='" + remoteChangeRow.getRelatedFeatureCode()+ "'"); |
1473 |
|
1474 |
ef = target.createNewFeature(f); |
1475 |
ef.setString(lentity.getFeatureIdFieldName(), this.createUniqueCode());
|
1476 |
|
1477 |
target.insert(ef); |
1478 |
this.addChange(lentity, OP_INSERT, changesStore, ef);
|
1479 |
|
1480 |
} |
1481 |
break;
|
1482 |
} |
1483 |
status.incrementCurrentValue(); |
1484 |
} |
1485 |
changesStore.finishEditing(); |
1486 |
target.finishEditing(); |
1487 |
} |
1488 |
} |
1489 |
remoteChangesTable.delete(this, lentity.getEntityCode());
|
1490 |
status.message("Updating metadata tables");
|
1491 |
status.terminate(); |
1492 |
if(lentity.getLocalRevisionCode() == null){ |
1493 |
lentity.setLocalRevisionCode(lentity.getRepositoryRevisionCode()); |
1494 |
lentity.insert(); |
1495 |
} else {
|
1496 |
lentity.setLocalRevisionCode(lentity.getRepositoryRevisionCode()); |
1497 |
lentity.update(); |
1498 |
} |
1499 |
reloadWorkspaceEntities(); |
1500 |
|
1501 |
status.message("Update completed");
|
1502 |
status.terminate(); |
1503 |
return ERR_OK;
|
1504 |
} catch (Exception ex) { |
1505 |
LOGGER.warn("Can't update.", ex);
|
1506 |
status.message("Can't update");
|
1507 |
status.abort(); |
1508 |
if(target != null){ |
1509 |
target.cancelEditingQuietly(); |
1510 |
} |
1511 |
if(changesStore != null){ |
1512 |
changesStore.cancelEditingQuietly(); |
1513 |
} |
1514 |
return ERR_CANT_UPDATE;
|
1515 |
} finally {
|
1516 |
this.removeStoreIgnoreChanges(target);
|
1517 |
DisposeUtils.disposeQuietly(features); |
1518 |
DisposeUtils.disposeQuietly(target); |
1519 |
DisposeUtils.disposeQuietly(changesStore); |
1520 |
} |
1521 |
} |
1522 |
|
1523 |
@Override
|
1524 |
public JDBCServerExplorer getExplorer() {
|
1525 |
return this.wsexplorer; |
1526 |
} |
1527 |
|
1528 |
@Override
|
1529 |
public int log(String tableName, int maxRevisions, int operation, SimpleTaskStatus status){ |
1530 |
|
1531 |
|
1532 |
FeatureStore target = null;
|
1533 |
int errcode = ERR_OK;
|
1534 |
VCSGisLogRequest request = null;
|
1535 |
if( status==null ) { |
1536 |
status = ToolsLocator.getTaskStatusManager().createDefaultSimpleTaskStatus( |
1537 |
"Log "+tableName
|
1538 |
); |
1539 |
status.setAutoremove(true);
|
1540 |
status.add(); |
1541 |
} |
1542 |
try {
|
1543 |
LOGGER.debug("===: LOG "+this.getCode()+", '"+this.getLabel()+"', "+tableName); |
1544 |
reloadRepositoryEntities(status); |
1545 |
|
1546 |
//TODO calcular las revisiones que tengo para excluirlas
|
1547 |
EntityRow lentity = this.getWorkspaceEntityByName(tableName);
|
1548 |
if(lentity == null){ |
1549 |
status.message("Can't find table '"+tableName+"'"); |
1550 |
status.abort(); |
1551 |
return ERR_ENTITY_NOT_EXISTS;
|
1552 |
} |
1553 |
|
1554 |
|
1555 |
LocalRevisionsTable localRevisionsTable = new LocalRevisionsTable();
|
1556 |
GetItemWithSizeAndIterator64<Feature> lrevisions = localRevisionsTable.getAllRevisions(this, lentity.getEntityCode());
|
1557 |
//Asumimos que lrevisions esta ordenado ascendentemente por numero de revision
|
1558 |
// Long prevRevNumber = null;
|
1559 |
Long minRevision = null; |
1560 |
Long maxRevision = null; |
1561 |
for (Feature lrevision : lrevisions) {
|
1562 |
LocalRevisionRow x = new LocalRevisionRow(this, lrevision); |
1563 |
Long revNumber = x.getNumber();
|
1564 |
//Asumimos que las revisiones que tenemos son consecutivas
|
1565 |
// if(prevRevNumber != null && revNumber != prevRevNumber+1){ //Salto
|
1566 |
//Borrar la tabla completamente ???
|
1567 |
// target = this.getFeatureStore(LocalRevisionsTable.TABLE_NAME);
|
1568 |
// target.edit(MODE_PASS_THROUGH);
|
1569 |
// target.delete
|
1570 |
// }
|
1571 |
if(minRevision == null){ |
1572 |
minRevision = revNumber; |
1573 |
} |
1574 |
maxRevision = revNumber; |
1575 |
} |
1576 |
|
1577 |
status.message("Executing log request");
|
1578 |
request = this.repository.createLogRequest(tableName);
|
1579 |
if(minRevision != null && maxRevision != null){ |
1580 |
request.setExcludeRevisionsRange(Range.between(minRevision, maxRevision)); |
1581 |
} |
1582 |
request.setOperation(operation); |
1583 |
request.setMaxRevisions(maxRevisions); |
1584 |
|
1585 |
if( request.execute()!=ERR_OK ) {
|
1586 |
status.message("Can't retriev history of "+tableName+" (error "+request.getLastErrorCode()+")"); |
1587 |
status.abort(); |
1588 |
return request.getLastErrorCode();
|
1589 |
} |
1590 |
|
1591 |
status.message("Deleting previous local revision information");
|
1592 |
errcode = ERR_CANT_OPEN_STORE; |
1593 |
target = this.getFeatureStore(LocalRevisionsTable.TABLE_NAME);
|
1594 |
errcode = ERR_CANT_RETRIEVE_SOURCE_FEATURES; |
1595 |
DisposableIterable<VCSGisRevision> revisions = request.getRevisions(); |
1596 |
status.message("Adding to local revisions");
|
1597 |
long sz = ContainerUtils.size64(revisions);
|
1598 |
status.setRangeOfValues(0, sz);
|
1599 |
status.setCurValue(0);
|
1600 |
|
1601 |
errcode = ERR_CANT_INSERT_FEATURES; |
1602 |
target.edit(FeatureStore.MODE_PASS_THROUGH); |
1603 |
for (VCSGisRevision revision : revisions) {
|
1604 |
if(operation == VCSGisLogRequest.LOG_OP_LAST && revision.getNumber()!=maxRevision+1){ |
1605 |
//Borrar todo el target ???
|
1606 |
} |
1607 |
EditableFeature f = target.createNewFeature(); |
1608 |
LocalRevisionRow row = new LocalRevisionRow(this, f); |
1609 |
row.copyFrom(revision); |
1610 |
row.insert(target); |
1611 |
status.incrementCurrentValue(); |
1612 |
} |
1613 |
target.finishEditing(); |
1614 |
status.message("Log completed");
|
1615 |
status.terminate(); |
1616 |
return ERR_OK;
|
1617 |
} catch (Exception ex) { |
1618 |
LOGGER.warn("Can't retrieve history.", ex);
|
1619 |
status.message("Can't retrieve history");
|
1620 |
status.abort(); |
1621 |
return errcode;
|
1622 |
} finally {
|
1623 |
DisposeUtils.disposeQuietly(request); |
1624 |
if(target != null) { |
1625 |
this.removeStoreIgnoreChanges(target);
|
1626 |
} |
1627 |
DisposeUtils.disposeQuietly(target); |
1628 |
} |
1629 |
} |
1630 |
|
1631 |
@Override
|
1632 |
public List<VCSGisWorkspaceRevision> getRemoteRevisions(String tableName) { |
1633 |
// LocalRevisionsTable table = new LocalRevisionsTable();
|
1634 |
// features = table.getAllRevisions(this, tableName);
|
1635 |
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. |
1636 |
} |
1637 |
|
1638 |
@Override
|
1639 |
public List<VCSGisEntity> getRepositoryEntities() { |
1640 |
return this.getRepositoryEntities(null); |
1641 |
} |
1642 |
|
1643 |
@Override
|
1644 |
public List<VCSGisEntity> getRepositoryEntities(SimpleTaskStatus status) { |
1645 |
if( status==null ) { |
1646 |
status = ToolsLocator.getTaskStatusManager().createDefaultSimpleTaskStatus("Repository tables");
|
1647 |
status.setAutoremove(true);
|
1648 |
status.add(); |
1649 |
} |
1650 |
try {
|
1651 |
status.message("Getting repository table metadata");
|
1652 |
VCSGisEntitiesRequest request = this.getRepository().createEntitiesRequest();
|
1653 |
request.execute(); |
1654 |
List<VCSGisEntity> entities = request.getRepositoryEntities();
|
1655 |
request.dispose(); |
1656 |
|
1657 |
Map<String, VCSGisEntity> tmp = new HashMap<>(); |
1658 |
entities.forEach(entity -> { |
1659 |
tmp.put(entity.getEntityCode(), entity); |
1660 |
}); |
1661 |
this.repositoryEntitiesByCode = tmp;
|
1662 |
|
1663 |
|
1664 |
status.message("Repository tables metadata update completed");
|
1665 |
status.terminate(); |
1666 |
return entities;
|
1667 |
} catch (Exception ex) { |
1668 |
LOGGER.warn("Can't get repository tables metadata.", ex);
|
1669 |
status.message("Can't get repository tables metadata");
|
1670 |
status.abort(); |
1671 |
return null; |
1672 |
} |
1673 |
|
1674 |
} |
1675 |
|
1676 |
@Override
|
1677 |
public boolean updateNeedMerge(String entityName) { |
1678 |
RemoteChangesTable remoteChangesTable = new RemoteChangesTable();
|
1679 |
|
1680 |
VCSGisEntity entity = this.getWorkspaceEntity(entityName);
|
1681 |
if(entity == null){ |
1682 |
entity = this.getRepositoryEntity(entityName);
|
1683 |
} |
1684 |
|
1685 |
return remoteChangesTable.updateNeedMerge(this, entity.getEntityCode()); |
1686 |
} |
1687 |
|
1688 |
} |