001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.command.conflict; 003 004import static org.openstreetmap.josm.tools.I18n.tr; 005 006import java.util.Collection; 007import java.util.Set; 008 009import javax.swing.Icon; 010 011import org.openstreetmap.josm.data.conflict.Conflict; 012import org.openstreetmap.josm.data.osm.OsmPrimitive; 013import org.openstreetmap.josm.gui.conflict.pair.MergeDecisionType; 014import org.openstreetmap.josm.tools.ImageProvider; 015 016/** 017 * Represents the resolution of a conflict between the deleted flag of two {@link OsmPrimitive}s. 018 * @since 1654 019 */ 020public class DeletedStateConflictResolveCommand extends ConflictResolveCommand { 021 022 /** the conflict to resolve */ 023 private final Conflict<? extends OsmPrimitive> conflict; 024 025 /** the merge decision */ 026 private final MergeDecisionType decision; 027 028 /** 029 * Constructs a new {@code DeletedStateConflictResolveCommand}. 030 * 031 * @param conflict the conflict data set 032 * @param decision the merge decision 033 */ 034 public DeletedStateConflictResolveCommand(Conflict<? extends OsmPrimitive> conflict, MergeDecisionType decision) { 035 this.conflict = conflict; 036 this.decision = decision; 037 } 038 039 @Override 040 public String getDescriptionText() { 041 return tr("Resolve conflicts in deleted state in {0}", conflict.getMy().getId()); 042 } 043 044 @Override 045 public Icon getDescriptionIcon() { 046 return ImageProvider.get("data", "object"); 047 } 048 049 @Override 050 public boolean executeCommand() { 051 // remember the current state of modified primitives, i.e. of OSM primitive 'my' 052 super.executeCommand(); 053 054 if (decision.equals(MergeDecisionType.KEEP_MINE)) { 055 if (conflict.getMy().isDeleted() || conflict.isMyDeleted()) { 056 // because my was involved in a conflict it my still be referred 057 // to from a way or a relation. Fix this now. 058 deleteMy(); 059 } 060 } else if (decision.equals(MergeDecisionType.KEEP_THEIR)) { 061 if (conflict.getTheir().isDeleted()) { 062 deleteMy(); 063 } else { 064 conflict.getMy().setDeleted(false); 065 } 066 } else 067 // should not happen 068 throw new IllegalStateException(tr("Cannot resolve undecided conflict.")); 069 070 rememberConflict(conflict); 071 return true; 072 } 073 074 private void deleteMy() { 075 Set<OsmPrimitive> referrers = getLayer().data.unlinkReferencesToPrimitive(conflict.getMy()); 076 for (OsmPrimitive p : referrers) { 077 if (!p.isNew() && !p.isDeleted()) { 078 p.setModified(true); 079 } 080 } 081 conflict.getMy().setDeleted(true); 082 } 083 084 @Override 085 public void fillModifiedData(Collection<OsmPrimitive> modified, Collection<OsmPrimitive> deleted, 086 Collection<OsmPrimitive> added) { 087 modified.add(conflict.getMy()); 088 modified.addAll(conflict.getMy().getReferrers()); 089 } 090 091 @Override 092 public int hashCode() { 093 final int prime = 31; 094 int result = super.hashCode(); 095 result = prime * result + ((conflict == null) ? 0 : conflict.hashCode()); 096 result = prime * result + ((decision == null) ? 0 : decision.hashCode()); 097 return result; 098 } 099 100 @Override 101 public boolean equals(Object obj) { 102 if (this == obj) 103 return true; 104 if (!super.equals(obj)) 105 return false; 106 if (getClass() != obj.getClass()) 107 return false; 108 DeletedStateConflictResolveCommand other = (DeletedStateConflictResolveCommand) obj; 109 if (conflict == null) { 110 if (other.conflict != null) 111 return false; 112 } else if (!conflict.equals(other.conflict)) 113 return false; 114 if (decision != other.decision) 115 return false; 116 return true; 117 } 118}