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.Objects; 007 008import org.openstreetmap.josm.Main; 009import org.openstreetmap.josm.command.Command; 010import org.openstreetmap.josm.data.conflict.Conflict; 011import org.openstreetmap.josm.data.conflict.ConflictCollection; 012import org.openstreetmap.josm.gui.layer.OsmDataLayer; 013 014/** 015 * This is the common base class for {@link Command}s which manipulate {@link Conflict}s in 016 * addition to {@link org.openstreetmap.josm.data.osm.OsmPrimitive}s. 017 * 018 * A ConflictResolverCommand can remember a collection of conflicts it resolves. Upon undoing 019 * it reconstitutes them. 020 * 021 */ 022public abstract class ConflictResolveCommand extends Command { 023 /** the list of resolved conflicts */ 024 private final ConflictCollection resolvedConflicts; 025 026 /** 027 * Constructs a new {@code ConflictResolveCommand} in the context of the current edit layer, if any. 028 */ 029 public ConflictResolveCommand() { 030 super(); 031 resolvedConflicts = new ConflictCollection(); 032 } 033 034 /** 035 * Constructs a new {@code ConflictResolveCommand} in the context of a given data layer. 036 * @param layer the data layer. Must not be null. 037 */ 038 public ConflictResolveCommand(OsmDataLayer layer) { 039 super(layer); 040 resolvedConflicts = new ConflictCollection(); 041 } 042 043 /** 044 * remembers a conflict in the internal list of remembered conflicts 045 * 046 * @param c the remembered conflict 047 */ 048 protected void rememberConflict(Conflict<?> c) { 049 if (!resolvedConflicts.hasConflictForMy(c.getMy())) { 050 resolvedConflicts.add(c); 051 } 052 } 053 054 /** 055 * reconstitutes all remembered conflicts. Add the remembered conflicts to the 056 * set of conflicts of the {@link OsmDataLayer} this command was applied to. 057 * 058 */ 059 protected void reconstituteConflicts() { 060 OsmDataLayer editLayer = getLayer(); 061 for (Conflict<?> c : resolvedConflicts) { 062 if (!editLayer.getConflicts().hasConflictForMy(c.getMy())) { 063 editLayer.getConflicts().add(c); 064 } 065 } 066 } 067 068 @Override 069 public void undoCommand() { 070 super.undoCommand(); 071 072 if (Main.isDisplayingMapView()) { 073 if (!Main.getLayerManager().containsLayer(getLayer())) { 074 Main.warn(tr("Cannot undo command ''{0}'' because layer ''{1}'' is not present any more", 075 this.toString(), 076 getLayer().toString() 077 )); 078 return; 079 } 080 081 Main.getLayerManager().setActiveLayer(getLayer()); 082 } 083 reconstituteConflicts(); 084 } 085 086 @Override 087 public int hashCode() { 088 return Objects.hash(super.hashCode(), resolvedConflicts); 089 } 090 091 @Override 092 public boolean equals(Object obj) { 093 if (this == obj) return true; 094 if (obj == null || getClass() != obj.getClass()) return false; 095 if (!super.equals(obj)) return false; 096 ConflictResolveCommand that = (ConflictResolveCommand) obj; 097 return Objects.equals(resolvedConflicts, that.resolvedConflicts); 098 } 099}