Changeset 5413 in josm for trunk/src/org/openstreetmap


Ignore:
Timestamp:
2012-08-09T23:56:29+02:00 (12 years ago)
Author:
Don-vip
Message:

fix #7938 - fix StackOverflowError when painting conflicts of a cyclic relation (patch by verdy_p) + improve javadoc

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/gui/dialogs/ConflictDialog.java

    r5297 r5413  
    1515import java.util.Arrays;
    1616import java.util.Collection;
     17import java.util.HashSet;
    1718import java.util.Iterator;
    1819import java.util.LinkedList;
     20import java.util.Set;
    1921import java.util.concurrent.CopyOnWriteArrayList;
    2022
     
    5759public final class ConflictDialog extends ToggleDialog implements MapView.EditLayerChangeListener, IConflictListener, SelectionChangedListener{
    5860
     61    /**
     62     * Replies the color used to paint conflicts.
     63     *
     64     * @return the color used to paint conflicts
     65     * @since 1221
     66     * @see #paintConflicts
     67     */
    5968    static public Color getColor() {
    6069        return Main.pref.getColor(marktr("conflict"), Color.gray);
    6170    }
    6271
    63     /** the  collection of conflicts displayed by this conflict dialog*/
     72    /** the collection of conflicts displayed by this conflict dialog */
    6473    private ConflictCollection conflicts;
    6574
     
    176185
    177186    /**
    178      * Paint all conflicts that can be expressed on the main window.
     187     * Paints all conflicts that can be expressed on the main window.
     188     *
     189     * @param g The {@code Graphics} used to paint
     190     * @param nc The {@code NavigatableComponent} used to get screen coordinates of nodes
     191     * @since 86
    179192     */
    180193    public void paintConflicts(final Graphics g, final NavigatableComponent nc) {
     
    183196            return;
    184197        g.setColor(preferencesColor);
    185         Visitor conflictPainter = new AbstractVisitor(){
     198        Visitor conflictPainter = new AbstractVisitor() {
     199            // Manage a stack of visited relations to avoid infinite recursion with cyclic relations (fix #7938)
     200            private final Set<Relation> visited = new HashSet<Relation>();
    186201            public void visit(Node n) {
    187202                Point p = nc.getPoint(n);
     
    206221            public void visit(Relation e) {
    207222                for (RelationMember em : e.getMembers()) {
    208                     em.getMember().visit(this);
     223                    OsmPrimitive m = em.getMember();
     224                    if (m instanceof Node || m instanceof Way) {
     225                        m.visit(this);
     226                    } else if (m instanceof Relation && !visited.contains(m)) {
     227                        visited.add((Relation) m);
     228                        try {
     229                            m.visit(this);
     230                        } finally {
     231                            visited.remove(m);
     232                        }
     233                    }
    209234                }
    210235            }
Note: See TracChangeset for help on using the changeset viewer.