| 164 | | for (OsmPrimitive source: deletedObjectsToUnlink) { |
| 165 | | OsmPrimitive target = getMergeTarget(source); |
| 166 | | if (target == null) |
| 167 | | throw new RuntimeException(tr("Missing merge target for object with id {0}", source.getUniqueId())); |
| 168 | | targetDataSet.unlinkReferencesToPrimitive(target); |
| | 165 | |
| | 166 | deleteMarkedObjects(); |
| | 167 | } |
| | 168 | |
| | 169 | /** |
| | 170 | * Deleted objects in objectsToDelete set and create conflicts for objects that cannot |
| | 171 | * be deleted because they're referenced in the target dataset. |
| | 172 | */ |
| | 173 | protected void deleteMarkedObjects() { |
| | 174 | boolean flag; |
| | 175 | do { |
| | 176 | flag = false; |
| | 177 | for (Iterator<OsmPrimitive> it = objectsToDelete.iterator();it.hasNext();) { |
| | 178 | OsmPrimitive target = it.next(); |
| | 179 | OsmPrimitive source = sourceDataSet.getPrimitiveById(target.getPrimitiveId()); |
| | 180 | if (source == null) |
| | 181 | throw new RuntimeException(tr("Object of type {0} with id {1} was marked to be deleted, but it's missing in the source dataset", |
| | 182 | target.getType(), target.getUniqueId())); |
| | 183 | |
| | 184 | List<OsmPrimitive> referrers = target.getReferrers(); |
| | 185 | if (referrers.isEmpty()) { |
| | 186 | target.setDeleted(true); |
| | 187 | target.mergeFrom(source); |
| | 188 | it.remove(); |
| | 189 | flag = true; |
| | 190 | } else { |
| | 191 | for (OsmPrimitive referrer : referrers) { |
| | 192 | // If one of object referrers isn't going to be deleted, |
| | 193 | // add a conflict and don't delete the object |
| | 194 | if (!objectsToDelete.contains(referrer)) { |
| | 195 | conflicts.add(target, source); |
| | 196 | it.remove(); |
| | 197 | flag = true; |
| | 198 | break; |
| | 199 | } |
| | 200 | } |
| | 201 | } |
| | 202 | |
| | 203 | } |
| | 204 | } while (flag); |
| | 205 | |
| | 206 | if (!objectsToDelete.isEmpty()) { |
| | 207 | // There are some more objects rest in the objectsToDelete set |
| | 208 | // This can be because of cross-referenced relations. |
| | 209 | for (OsmPrimitive osm: objectsToDelete) { |
| | 210 | if (osm instanceof Way) { |
| | 211 | ((Way) osm).setNodes(null); |
| | 212 | } else if (osm instanceof Relation) { |
| | 213 | ((Relation) osm).setMembers(null); |
| | 214 | } |
| | 215 | } |
| | 216 | for (OsmPrimitive osm: objectsToDelete) { |
| | 217 | osm.setDeleted(true); |
| | 218 | osm.mergeFrom(sourceDataSet.getPrimitiveById(osm.getPrimitiveId())); |
| | 219 | } |
| 259 | | } else if (target.isDeleted() && ! source.isDeleted() && target.getVersion() == source.getVersion()) { |
| | 310 | } else if (target.isVisible() != source.isVisible() && target.getVersion() == source.getVersion()) |
| | 311 | // Same version, but different "visible" attribute. It indicates a serious problem in datasets. |
| | 312 | // For example, datasets can be fetched from different OSM servers or badly hand-modified. |
| | 313 | // We shouldn't merge that datasets. |
| | 314 | throw new DataIntegrityProblemException(tr("Conflict in 'visible' attribute for object of type {0} with id {1}", |
| | 315 | target.getType(), target.getId())); |
| | 316 | else if (target.isDeleted() && ! source.isDeleted() && target.getVersion() == source.getVersion()) { |
| 278 | | // clone it into target. But check first, whether source is deleted. if so, |
| 279 | | // make sure that target is not referenced any more in myDataSet. If it is there |
| 280 | | // is a conflict |
| 281 | | if (source.isDeleted()) { |
| 282 | | if (!target.getReferrers().isEmpty()) { |
| 283 | | conflicts.add(target, source); |
| 284 | | } |
| 285 | | } else { |
| 286 | | target.mergeFrom(source); |
| 287 | | objectsWithChildrenToMerge.add(source.getPrimitiveId()); |
| 288 | | } |
| | 335 | // clone it into target. |
| | 336 | target.mergeFrom(source); |
| | 337 | objectsWithChildrenToMerge.add(source.getPrimitiveId()); |