24 |
24 |
|
25 |
25 |
package org.gvsig.fmap.dal.feature.impl;
|
26 |
26 |
|
27 |
|
import org.gvsig.fmap.dal.feature.impl.editing.memory.SpatialManager;
|
28 |
|
import org.gvsig.fmap.dal.feature.impl.editing.memory.FeatureTypeManager;
|
29 |
|
import org.gvsig.fmap.dal.feature.impl.editing.memory.FeatureManager;
|
30 |
|
|
31 |
27 |
import java.util.ArrayList;
|
32 |
28 |
import java.util.Collection;
|
33 |
29 |
import java.util.Collections;
|
... | ... | |
39 |
35 |
import java.util.Map.Entry;
|
40 |
36 |
import java.util.Set;
|
41 |
37 |
import javax.json.JsonObject;
|
42 |
|
|
43 |
38 |
import org.apache.commons.io.FilenameUtils;
|
44 |
39 |
import org.apache.commons.io.IOUtils;
|
45 |
40 |
import org.apache.commons.lang3.StringUtils;
|
... | ... | |
50 |
45 |
import org.gvsig.expressionevaluator.ExpressionUtils;
|
51 |
46 |
import org.gvsig.expressionevaluator.GeometryExpressionUtils;
|
52 |
47 |
import org.gvsig.fmap.dal.BaseStoresRepository;
|
53 |
|
|
54 |
48 |
import org.gvsig.fmap.dal.DALLocator;
|
55 |
49 |
import org.gvsig.fmap.dal.DataManager;
|
56 |
50 |
import org.gvsig.fmap.dal.DataQuery;
|
... | ... | |
91 |
85 |
import org.gvsig.fmap.dal.feature.FeatureStore;
|
92 |
86 |
import org.gvsig.fmap.dal.feature.FeatureStoreNotification;
|
93 |
87 |
import org.gvsig.fmap.dal.feature.FeatureStoreProviderFactory;
|
|
88 |
import org.gvsig.fmap.dal.feature.FeatureStoreTimeSupport;
|
|
89 |
import org.gvsig.fmap.dal.feature.FeatureStoreTransform;
|
94 |
90 |
import org.gvsig.fmap.dal.feature.FeatureStoreTransforms;
|
95 |
91 |
import org.gvsig.fmap.dal.feature.FeatureType;
|
|
92 |
import org.gvsig.fmap.dal.feature.FeatureType.FeatureTypeChanged;
|
96 |
93 |
import org.gvsig.fmap.dal.feature.NewFeatureStoreParameters;
|
97 |
|
import org.gvsig.fmap.dal.feature.FeatureStoreTimeSupport;
|
98 |
|
import org.gvsig.fmap.dal.feature.FeatureStoreTransform;
|
99 |
|
import org.gvsig.fmap.dal.feature.FeatureType.FeatureTypeChanged;
|
100 |
94 |
import org.gvsig.fmap.dal.feature.exception.AlreadyEditingException;
|
101 |
95 |
import org.gvsig.fmap.dal.feature.exception.ConcurrentDataModificationException;
|
102 |
96 |
import org.gvsig.fmap.dal.feature.exception.CreateFeatureException;
|
... | ... | |
122 |
116 |
import org.gvsig.fmap.dal.feature.exception.StoreUpdateFeatureTypeException;
|
123 |
117 |
import org.gvsig.fmap.dal.feature.exception.ValidateFeaturesException;
|
124 |
118 |
import org.gvsig.fmap.dal.feature.exception.WriteNotAllowedException;
|
|
119 |
import org.gvsig.fmap.dal.feature.impl.dynobjectutils.DynObjectFeatureFacade;
|
|
120 |
import org.gvsig.fmap.dal.feature.impl.editing.memory.FeatureManager;
|
|
121 |
import org.gvsig.fmap.dal.feature.impl.editing.memory.FeatureTypeManager;
|
|
122 |
import org.gvsig.fmap.dal.feature.impl.editing.memory.SpatialManager;
|
125 |
123 |
import org.gvsig.fmap.dal.feature.impl.featureset.DefaultFeatureSet;
|
126 |
|
import org.gvsig.fmap.dal.feature.impl.dynobjectutils.DynObjectFeatureFacade;
|
127 |
124 |
import org.gvsig.fmap.dal.feature.impl.undo.DefaultFeatureCommandsStack;
|
128 |
125 |
import org.gvsig.fmap.dal.feature.impl.undo.FeatureCommandsStack;
|
129 |
126 |
import org.gvsig.fmap.dal.feature.paging.FeaturePagingHelper;
|
... | ... | |
168 |
165 |
import org.gvsig.tools.persistence.Persistent;
|
169 |
166 |
import org.gvsig.tools.persistence.PersistentState;
|
170 |
167 |
import org.gvsig.tools.persistence.exception.PersistenceException;
|
|
168 |
import org.gvsig.tools.resourcesstorage.ResourcesStorage;
|
171 |
169 |
import org.gvsig.tools.undo.RedoException;
|
172 |
170 |
import org.gvsig.tools.undo.UndoException;
|
173 |
171 |
import org.gvsig.tools.undo.command.Command;
|
|
172 |
import org.gvsig.tools.util.GetItemWithSizeIsEmptyAndIterator64;
|
174 |
173 |
import org.gvsig.tools.util.HasAFile;
|
175 |
|
import org.gvsig.tools.resourcesstorage.ResourcesStorage;
|
176 |
|
import org.gvsig.tools.util.GetItemWithSize64;
|
177 |
|
import org.gvsig.tools.util.GetItemWithSizeAndIterator64;
|
178 |
|
import org.gvsig.tools.util.GetItemWithSizeIsEmptyAndIterator64;
|
179 |
174 |
import org.gvsig.tools.util.PropertiesSupportHelper;
|
180 |
175 |
import org.gvsig.tools.util.UnmodifiableBasicMap;
|
181 |
176 |
import org.gvsig.tools.visitor.VisitCanceledException;
|
... | ... | |
1203 |
1198 |
hasInserts = false;
|
1204 |
1199 |
notifyChange(FeatureStoreNotification.AFTER_STARTEDITING);
|
1205 |
1200 |
break;
|
|
1201 |
case MODE_PASS_THROUGH:
|
|
1202 |
if(!this.provider.supportsPassThroughMode()){
|
|
1203 |
throw new IllegalStateException(this.getName());
|
|
1204 |
}
|
|
1205 |
if (!this.transforms.isEmpty()) {
|
|
1206 |
throw new IllegalStateException(this.getName());
|
|
1207 |
}
|
|
1208 |
if( notifyChange(FeatureStoreNotification.BEFORE_STARTEDITING).isCanceled() ) {
|
|
1209 |
return;
|
|
1210 |
}
|
|
1211 |
invalidateIndexes();
|
|
1212 |
this.mode = MODE_PASS_THROUGH;
|
|
1213 |
hasInserts = false;
|
|
1214 |
notifyChange(FeatureStoreNotification.AFTER_STARTEDITING);
|
|
1215 |
break;
|
|
1216 |
|
|
1217 |
|
1206 |
1218 |
}
|
1207 |
1219 |
} catch (Exception e) {
|
1208 |
1220 |
throw new StoreEditException(e, this.getName());
|
... | ... | |
1286 |
1298 |
if (type == null) {
|
1287 |
1299 |
throw new NullFeatureTypeException(getName());
|
1288 |
1300 |
}
|
1289 |
|
if (mode == MODE_QUERY && type.hasOnlyMetadataChanges(this.defaultFeatureType)) {
|
1290 |
|
if( notifyChange(FeatureStoreNotification.BEFORE_UPDATE_TYPE, type).isCanceled() ) {
|
1291 |
|
return;
|
1292 |
|
}
|
1293 |
|
FeatureType theType = type.getNotEditableCopy();
|
1294 |
|
if( defaultFeatureType.getId().equals(theType.getId()) ) {
|
1295 |
|
defaultFeatureType = theType;
|
1296 |
|
}
|
1297 |
|
List newtypes = new ArrayList();
|
1298 |
|
for (FeatureType featureType : this.featureTypes) {
|
1299 |
|
if( featureType.getId().equals(theType.getId()) ) {
|
1300 |
|
newtypes.add(theType);
|
1301 |
|
} else {
|
1302 |
|
newtypes.add(featureType);
|
1303 |
|
}
|
1304 |
|
}
|
1305 |
|
this.featureTypes = newtypes;
|
1306 |
|
saveDALFile();
|
1307 |
|
notifyChange(FeatureStoreNotification.AFTER_UPDATE_TYPE, type);
|
1308 |
|
return ;
|
1309 |
|
}
|
1310 |
|
boolean typehasStrongChanges = ((DefaultEditableFeatureType) type).hasStrongChanges();
|
1311 |
|
if (typehasStrongChanges) {
|
1312 |
|
checkInEditingMode();
|
1313 |
|
} else if(this.isAppending()) {
|
1314 |
|
throw new NeedEditingModeException(this.getName());
|
1315 |
|
}
|
1316 |
|
// FIXME: Comprobar que es un featureType aceptable.
|
1317 |
|
if( notifyChange(FeatureStoreNotification.BEFORE_UPDATE_TYPE, type).isCanceled() ) {
|
1318 |
|
return;
|
1319 |
|
}
|
1320 |
|
newVersionOfUpdate();
|
1321 |
1301 |
|
1322 |
|
FeatureType oldt = type.getSource().getCopy();
|
1323 |
|
FeatureType newt = type.getCopy();
|
1324 |
|
commands.update(newt, oldt);
|
1325 |
|
if (typehasStrongChanges) {
|
1326 |
|
hasStrongChanges = true;
|
|
1302 |
switch(this.mode) {
|
|
1303 |
case MODE_QUERY:
|
|
1304 |
if (type.hasOnlyMetadataChanges(this.defaultFeatureType)) {
|
|
1305 |
if( notifyChange(FeatureStoreNotification.BEFORE_UPDATE_TYPE, type).isCanceled() ) {
|
|
1306 |
return;
|
|
1307 |
}
|
|
1308 |
FeatureType theType = type.getNotEditableCopy();
|
|
1309 |
if( defaultFeatureType.getId().equals(theType.getId()) ) {
|
|
1310 |
defaultFeatureType = theType;
|
|
1311 |
}
|
|
1312 |
List newtypes = new ArrayList();
|
|
1313 |
for (FeatureType featureType : this.featureTypes) {
|
|
1314 |
if( featureType.getId().equals(theType.getId()) ) {
|
|
1315 |
newtypes.add(theType);
|
|
1316 |
} else {
|
|
1317 |
newtypes.add(featureType);
|
|
1318 |
}
|
|
1319 |
}
|
|
1320 |
this.featureTypes = newtypes;
|
|
1321 |
saveDALFile();
|
|
1322 |
notifyChange(FeatureStoreNotification.AFTER_UPDATE_TYPE, type);
|
|
1323 |
}
|
|
1324 |
|
|
1325 |
break;
|
|
1326 |
case MODE_FULLEDIT:
|
|
1327 |
if( notifyChange(FeatureStoreNotification.BEFORE_UPDATE_TYPE, type).isCanceled() ) {
|
|
1328 |
return;
|
|
1329 |
}
|
|
1330 |
newVersionOfUpdate();
|
|
1331 |
|
|
1332 |
FeatureType oldt = type.getSource().getCopy();
|
|
1333 |
FeatureType newt = type.getCopy();
|
|
1334 |
commands.update(newt, oldt);
|
|
1335 |
hasStrongChanges = ((DefaultEditableFeatureType) type).hasStrongChanges();
|
|
1336 |
notifyChange(FeatureStoreNotification.AFTER_UPDATE_TYPE, type);
|
|
1337 |
break;
|
|
1338 |
case MODE_APPEND:
|
|
1339 |
case MODE_PASS_THROUGH:
|
|
1340 |
throw new NeedEditingModeException(this.getName());
|
|
1341 |
|
1327 |
1342 |
}
|
1328 |
|
notifyChange(FeatureStoreNotification.AFTER_UPDATE_TYPE, type);
|
1329 |
1343 |
} catch (Exception e) {
|
1330 |
1344 |
throw new StoreUpdateFeatureTypeException(e, this.getName());
|
1331 |
1345 |
}
|
... | ... | |
1333 |
1347 |
|
1334 |
1348 |
@Override
|
1335 |
1349 |
public void delete(Feature feature) throws DataException {
|
1336 |
|
this.commands.delete(feature);
|
|
1350 |
switch (this.mode){
|
|
1351 |
case MODE_PASS_THROUGH:
|
|
1352 |
this.provider.passThroughDelete((FeatureReferenceProviderServices) feature.getReference());
|
|
1353 |
break;
|
|
1354 |
default:
|
|
1355 |
this.commands.delete(feature);
|
|
1356 |
break;
|
|
1357 |
|
|
1358 |
}
|
1337 |
1359 |
}
|
1338 |
1360 |
|
1339 |
1361 |
@Override
|
... | ... | |
1353 |
1375 |
boolean pendingFinishEditing = false;
|
1354 |
1376 |
DisposableFeatureSetIterable features = null;
|
1355 |
1377 |
try {
|
1356 |
|
if( !this.isEditing() ) {
|
1357 |
|
pendingFinishEditing = true;
|
1358 |
|
this.edit();
|
|
1378 |
switch(this.mode) {
|
|
1379 |
case MODE_QUERY:
|
|
1380 |
pendingFinishEditing = true;
|
|
1381 |
this.edit();
|
|
1382 |
break;
|
|
1383 |
case MODE_APPEND:
|
|
1384 |
throw new IllegalStateException("Delete not allowed in append mode.");
|
|
1385 |
case MODE_FULLEDIT:
|
|
1386 |
break;
|
|
1387 |
case MODE_PASS_THROUGH:
|
|
1388 |
// this.provider.passThroughDelete(filter);
|
|
1389 |
// return;
|
|
1390 |
break;
|
|
1391 |
default:
|
|
1392 |
throw new IllegalStateException("Mode "+this.mode+" not supported.");
|
1359 |
1393 |
}
|
|
1394 |
|
1360 |
1395 |
FeatureSet fset = this.getFeatureSet(filter);
|
1361 |
1396 |
features = fset.iterable();
|
1362 |
1397 |
for (Feature f : features) {
|
... | ... | |
1397 |
1432 |
}
|
1398 |
1433 |
}
|
1399 |
1434 |
|
|
1435 |
@Override
|
1400 |
1436 |
public synchronized void insert(FeatureSet set) throws DataException {
|
1401 |
1437 |
switch (mode) {
|
1402 |
1438 |
case MODE_QUERY:
|
... | ... | |
1404 |
1440 |
|
1405 |
1441 |
case MODE_APPEND:
|
1406 |
1442 |
case MODE_FULLEDIT:
|
|
1443 |
case MODE_PASS_THROUGH:
|
|
1444 |
try {
|
|
1445 |
set.accept((Object obj) -> {
|
|
1446 |
EditableFeature ef = createNewFeature((Feature) obj);
|
|
1447 |
insert(ef);
|
|
1448 |
});
|
|
1449 |
} catch (BaseException ex) {
|
|
1450 |
throw new StoreInsertFeatureException(ex, this.getName());
|
|
1451 |
}
|
1407 |
1452 |
break;
|
1408 |
1453 |
}
|
1409 |
|
try {
|
1410 |
|
set.accept((Object obj) -> {
|
1411 |
|
EditableFeature ef = createNewFeature((Feature) obj);
|
1412 |
|
insert(ef);
|
1413 |
|
});
|
1414 |
|
} catch (BaseException ex) {
|
1415 |
|
throw new StoreInsertFeatureException(ex, this.getName());
|
1416 |
|
}
|
1417 |
1454 |
}
|
1418 |
1455 |
|
1419 |
1456 |
private static EditableFeature lastChangedFeature = null;
|
... | ... | |
1449 |
1486 |
}
|
1450 |
1487 |
feature.validate(Feature.UPDATE);
|
1451 |
1488 |
commands.insert(feature);
|
|
1489 |
break;
|
|
1490 |
|
|
1491 |
case MODE_PASS_THROUGH:
|
|
1492 |
this.provider.passThroughInsert(((DefaultEditableFeature) feature).getData());
|
|
1493 |
break;
|
1452 |
1494 |
}
|
1453 |
1495 |
} catch (Exception e) {
|
1454 |
1496 |
throw new StoreInsertFeatureException(e, this.getName());
|
... | ... | |
1487 |
1529 |
@Override
|
1488 |
1530 |
public void update(EditableFeature feature)
|
1489 |
1531 |
throws DataException {
|
1490 |
|
if (feature.isUpdatable()) {
|
1491 |
|
commands.update(feature, feature.getSource());
|
1492 |
|
return;
|
|
1532 |
switch (this.mode){
|
|
1533 |
case MODE_PASS_THROUGH:
|
|
1534 |
this.provider.passThroughUpdate(((DefaultEditableFeature)feature).getData());
|
|
1535 |
break;
|
|
1536 |
case MODE_FULLEDIT:
|
|
1537 |
if (feature.isUpdatable()) {
|
|
1538 |
commands.update(feature, feature.getSource());
|
|
1539 |
return;
|
|
1540 |
}
|
|
1541 |
// FIXME: Deberiamos lanzar aqui un error en lugar de hacer el insert.
|
|
1542 |
// ?O lanzar un mensaje al log?
|
|
1543 |
insert(feature);
|
|
1544 |
break;
|
|
1545 |
default:
|
|
1546 |
throw new NeedEditingModeException(this.getName());
|
1493 |
1547 |
}
|
1494 |
|
// FIXME: Deberiamos lanzar aqui un error en lugar de hacer el insert.
|
1495 |
|
// ?O lanzar un mensaje al log?
|
1496 |
|
insert(feature);
|
1497 |
1548 |
}
|
1498 |
1549 |
|
1499 |
1550 |
@Override
|
... | ... | |
1518 |
1569 |
end = parameters.length-1;
|
1519 |
1570 |
}
|
1520 |
1571 |
|
1521 |
|
FeatureSet set = this.getFeatureSet(filter);
|
1522 |
|
DisposableIterator it = set.fastIterator();
|
1523 |
|
while (it.hasNext()) {
|
1524 |
|
Feature feature = (Feature) it.next();
|
1525 |
|
EditableFeature ef = feature.getEditable();
|
1526 |
|
for (int i = 0; i < end; i+=2) {
|
1527 |
|
String name = (String) parameters[i];
|
1528 |
|
Object value = parameters[i+1];
|
1529 |
|
ef.set(name, value);
|
|
1572 |
switch (this.mode){
|
|
1573 |
case MODE_PASS_THROUGH:
|
|
1574 |
// this.provider.passThroughUpdate(parameters, filter);
|
|
1575 |
// break;
|
|
1576 |
case MODE_FULLEDIT:
|
|
1577 |
FeatureSet set = this.getFeatureSet(filter);
|
|
1578 |
DisposableIterator it = set.fastIterator();
|
|
1579 |
while (it.hasNext()) {
|
|
1580 |
Feature feature = (Feature) it.next();
|
|
1581 |
EditableFeature ef = feature.getEditable();
|
|
1582 |
for (int i = 0; i < end; i+=2) {
|
|
1583 |
String name = (String) parameters[i];
|
|
1584 |
Object value = parameters[i+1];
|
|
1585 |
ef.set(name, value);
|
|
1586 |
}
|
|
1587 |
set.update(ef);
|
1530 |
1588 |
}
|
1531 |
|
set.update(ef);
|
|
1589 |
DisposeUtils.disposeQuietly(it);
|
|
1590 |
DisposeUtils.disposeQuietly(set);
|
|
1591 |
break;
|
|
1592 |
default:
|
|
1593 |
throw new NeedEditingModeException(this.getName());
|
1532 |
1594 |
}
|
1533 |
|
DisposeUtils.disposeQuietly(it);
|
1534 |
|
DisposeUtils.disposeQuietly(set);
|
1535 |
1595 |
}
|
1536 |
|
|
1537 |
|
|
1538 |
1596 |
|
1539 |
1597 |
synchronized public void doUpdate(EditableFeature feature, Feature oldFeature)
|
1540 |
1598 |
throws DataException {
|
... | ... | |
1652 |
1710 |
((FeatureSelection) this.getSelection()).deselectAll();
|
1653 |
1711 |
updateIndexes();
|
1654 |
1712 |
notifyChange(FeatureStoreNotification.AFTER_CANCELEDITING);
|
|
1713 |
break;
|
1655 |
1714 |
|
1656 |
1715 |
case MODE_FULLEDIT:
|
1657 |
1716 |
boolean clearSelection = this.hasStrongChanges;
|
... | ... | |
1666 |
1725 |
((FeatureSelection) this.getSelection()).deselectAll();
|
1667 |
1726 |
}
|
1668 |
1727 |
updateIndexes();
|
1669 |
|
notifyChange(FeatureStoreNotification.AFTER_CANCELEDITING);
|
|
1728 |
notifyChange(FeatureStoreNotification.AFTER_CANCELEDITING);
|
|
1729 |
break;
|
|
1730 |
|
|
1731 |
case MODE_PASS_THROUGH:
|
|
1732 |
if( notifyChange(FeatureStoreNotification.BEFORE_CANCELEDITING).isCanceled() ) {
|
|
1733 |
return;
|
|
1734 |
}
|
|
1735 |
exitEditingMode();
|
|
1736 |
((FeatureSelection) this.getSelection()).deselectAll();
|
|
1737 |
updateIndexes();
|
|
1738 |
notifyChange(FeatureStoreNotification.AFTER_CANCELEDITING);
|
|
1739 |
break;
|
1670 |
1740 |
}
|
1671 |
1741 |
} catch (Exception e) {
|
1672 |
1742 |
throw new StoreCancelEditingException(e, this.getName());
|
... | ... | |
1743 |
1813 |
featureManager.getInserted(),
|
1744 |
1814 |
featureManager.getUpdated(),
|
1745 |
1815 |
removeCalculatedAttributes(featureTypeManager.getFeatureTypesChanged()).iterator());
|
1746 |
|
|
|
1816 |
|
1747 |
1817 |
}
|
1748 |
1818 |
this.updateComputedFields(computedFields);
|
1749 |
1819 |
exitEditingMode();
|
... | ... | |
1751 |
1821 |
updateIndexes();
|
1752 |
1822 |
notifyChange(FeatureStoreNotification.AFTER_FINISHEDITING);
|
1753 |
1823 |
break;
|
|
1824 |
case MODE_PASS_THROUGH:
|
|
1825 |
if( selection!=null ) {
|
|
1826 |
selection = null;
|
|
1827 |
}
|
|
1828 |
if( notifyChange(FeatureStoreNotification.BEFORE_FINISHEDITING).isCanceled() ) {
|
|
1829 |
return;
|
|
1830 |
}
|
|
1831 |
exitEditingMode();
|
|
1832 |
updateIndexes();
|
|
1833 |
notifyChange(FeatureStoreNotification.AFTER_FINISHEDITING);
|
|
1834 |
break;
|
1754 |
1835 |
}
|
1755 |
1836 |
} catch (PerformEditingException pee) {
|
1756 |
1837 |
throw new WriteException(provider.getSourceId().toString(), pee);
|
... | ... | |
2014 |
2095 |
}
|
2015 |
2096 |
}
|
2016 |
2097 |
|
|
2098 |
@Override
|
2017 |
2099 |
public void copyTo(final FeatureStore target) {
|
2018 |
2100 |
boolean finishEditingAtEnd = false;
|
2019 |
2101 |
try {
|
... | ... | |
2803 |
2885 |
return new DefaultFeatureQuery();
|
2804 |
2886 |
}
|
2805 |
2887 |
|
|
2888 |
@Override
|
2806 |
2889 |
public FeatureQuery createFeatureQuery(Expression filter, String sortBy, boolean asc) {
|
2807 |
2890 |
FeatureQuery query = null;
|
2808 |
2891 |
if( filter!=null ) {
|
... | ... | |
2840 |
2923 |
return query;
|
2841 |
2924 |
}
|
2842 |
2925 |
|
|
2926 |
@Override
|
2843 |
2927 |
public FeatureQuery createFeatureQuery(String filter, String sortBy, boolean asc) {
|
2844 |
2928 |
if( StringUtils.isBlank(filter) ) {
|
2845 |
2929 |
return this.createFeatureQuery(
|
... | ... | |
3433 |
3517 |
return this.propertiesSupportHelper.getProperties();
|
3434 |
3518 |
}
|
3435 |
3519 |
|
|
3520 |
|
3436 |
3521 |
|
3437 |
3522 |
|
3438 |
3523 |
}
|