Ignore:
Timestamp:
2010-06-11T23:37:12+02:00 (15 years ago)
Author:
upliner
Message:

Better conflict handling and referrers checking

Location:
applications/editors/josm/plugins/reverter/src/reverter
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • applications/editors/josm/plugins/reverter/src/reverter/ChangesetReverter.java

    r21639 r21659  
    185185    }
    186186   
     187    private static Conflict<? extends OsmPrimitive> CreateConflict(OsmPrimitive p, boolean isMyDeleted) {
     188        switch (p.getType()) {
     189        case NODE:
     190            return new Conflict<Node>((Node)p,new Node((Node)p), isMyDeleted);
     191        case WAY:
     192            return new Conflict<Way>((Way)p,new Way((Way)p), isMyDeleted);
     193        case RELATION:
     194            return new Conflict<Relation>((Relation)p,new Relation((Relation)p), isMyDeleted);
     195        default: throw new AssertionError();
     196        }
     197    }
     198   
    187199    /**
    188200     * Builds a list of commands that will revert the changeset
     
    191203    public List<Command> getCommands() {
    192204        if (this.nds == null) return null;
    193         LinkedList<OsmPrimitive> toDelete = new LinkedList<OsmPrimitive>();
    194         LinkedList<Command> cmds = new LinkedList<Command>();
     205       
     206        //////////////////////////////////////////////////////////////////////////
     207        // Create commands to restore/update all affected objects
     208        LinkedList<Command> cmds = new DataSetToCmd(nds,ds).getCommandList();
     209
     210        //////////////////////////////////////////////////////////////////////////
     211        // Create a set of objects to be deleted
     212
     213        HashSet<OsmPrimitive> toDelete = new HashSet<OsmPrimitive>();
     214        // Mark objects that have visible=false to be deleted
    195215        for (OsmPrimitive p : nds.allPrimitives()) {
    196             if (p.isIncomplete()) continue;
    197             OsmPrimitive dp = ds.getPrimitiveById(p);
    198             if (dp == null)
    199                 throw new IllegalStateException(tr("Missing merge target for {0} with id {1}",
    200                         p.getType(), p.getUniqueId()));
    201             // Mark objects that have visible=false to be deleted
    202216            if (!p.isVisible()) {
    203                 toDelete.add(dp);
    204             }
    205         }
    206        
    207         // Check objects version
    208         Iterator<ChangesetDataSetEntry> iterator = cds.iterator();
    209         while (iterator.hasNext()) {
    210             ChangesetDataSetEntry entry = iterator.next();
    211             HistoryOsmPrimitive p = entry.getPrimitive();
    212             OsmPrimitive dp = ds.getPrimitiveById(p.getPrimitiveId());
    213             if (dp == null)
    214                 throw new IllegalStateException(tr("Missing merge target for {0} with id {1}",
    215                         p.getType(), p.getId()));
    216             OsmPrimitive np = nds.getPrimitiveById(p.getPrimitiveId());
    217             if (np == null && entry.getModificationType() != ChangesetModificationType.CREATED)
    218                 throw new IllegalStateException(tr("Missing new dataset object for {0} with id {1}",
    219                         p.getType(), p.getId()));
    220             if (p.getVersion() != dp.getVersion()
    221                     && (p.isVisible() || dp.isVisible())) {
    222                 Conflict<? extends OsmPrimitive> c;
    223                 switch (dp.getType()) {
    224                 case NODE:
    225                     if (np == null) {
    226                         np = new Node((Node)dp);
    227                         np.setDeleted(true);
    228                     }
    229                     c = new Conflict<Node>((Node)np,new Node((Node)dp),
    230                             entry.getModificationType() == ChangesetModificationType.CREATED);
    231                     break;
    232                 case WAY:
    233                     if (np == null) {
    234                         np = new Way((Way)dp);
    235                         np.setDeleted(true);
    236                     }
    237                     c = new Conflict<Way>((Way)np,new Way((Way)dp),
    238                             entry.getModificationType() == ChangesetModificationType.CREATED);
    239                     break;
    240                 case RELATION:
    241                     if (np == null) {
    242                         np = new Relation((Relation)dp);
    243                         np.setDeleted(true);
    244                     }
    245                     c = new Conflict<Relation>((Relation)np,new Relation((Relation)dp),
    246                             entry.getModificationType() == ChangesetModificationType.CREATED);
    247                     break;
    248                 default: throw new AssertionError();
    249                 }
    250                 cmds.add(new ConflictAddCommand(layer,c));
    251             }
    252         }
    253        
    254         // Create commands to restore/update all affected objects
    255         cmds.addAll(new DataSetToCmd(nds,ds).getCommandList());
    256        
     217                OsmPrimitive dp = ds.getPrimitiveById(p);
     218                if (dp != null) toDelete.add(dp);
     219            }
     220        }
    257221        // Mark all created objects to be deleted
    258222        for (HistoryOsmPrimitive id : created) {
     
    260224            if (p != null) toDelete.add(p);
    261225        }
     226       
     227
     228        //////////////////////////////////////////////////////////////////////////
     229        // Check reversion against current dataset and create necessary conflicts
     230       
     231        HashSet<OsmPrimitive> conflicted = new HashSet<OsmPrimitive>();
     232        // Check objects versions
     233        Iterator<ChangesetDataSetEntry> iterator = cds.iterator();
     234        while (iterator.hasNext()) {
     235            ChangesetDataSetEntry entry = iterator.next();
     236            HistoryOsmPrimitive hp = entry.getPrimitive();
     237            OsmPrimitive dp = ds.getPrimitiveById(hp.getPrimitiveId());
     238            if (dp == null)
     239                throw new IllegalStateException(tr("Missing merge target for {0} with id {1}",
     240                        hp.getType(), hp.getId()));
     241            if (hp.getVersion() != dp.getVersion()
     242                    && (hp.isVisible() || dp.isVisible())) {
     243                cmds.add(new ConflictAddCommand(layer,CreateConflict(dp,
     244                        entry.getModificationType() == ChangesetModificationType.CREATED)));
     245                conflicted.add(dp);
     246            }
     247        }
     248       
     249        /* Check referrers for deleted objects: if object is referred by another object that
     250         * isn't going to be deleted or modified, create a conflict.
     251         */
     252        for (OsmPrimitive p : toDelete.toArray(new OsmPrimitive[0])) {
     253            for (OsmPrimitive referrer : p.getReferrers()) {
     254                if (toDelete.contains(referrer)) continue; // object is going to be deleted
     255                if (nds.getPrimitiveById(referrer) != null)
     256                    continue; /* object is going to be modified so it cannot refer to
     257                               * objects created in same changeset
     258                               */
     259                if (!conflicted.contains(p)) {
     260                    cmds.add(new ConflictAddCommand(layer,CreateConflict(p, true)));
     261                    conflicted.add(p);
     262                }
     263                toDelete.remove(p);
     264                break;
     265            }
     266        }
     267       
    262268        // Create a Command to delete all marked objects
    263269        List<? extends OsmPrimitive> list;
  • applications/editors/josm/plugins/reverter/src/reverter/DataSetToCmd.java

    r21640 r21659  
    44
    55import java.util.ArrayList;
    6 import java.util.HashMap;
    76import java.util.LinkedList;
    87import java.util.List;
    9 import java.util.Map;
    108
    119import org.openstreetmap.josm.command.ChangeCommand;
Note: See TracChangeset for help on using the changeset viewer.