Ignore:
Timestamp:
2016-08-23T22:07:06+02:00 (8 years ago)
Author:
Don-vip
Message:

fix #13429 - Clean validator tree and use listener to find changes (patch by michael2402) - gsoc-core

File:
1 edited

Legend:

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

    r10715 r10880  
    1111import java.util.EnumMap;
    1212import java.util.Enumeration;
    13 import java.util.HashMap;
    1413import java.util.HashSet;
    1514import java.util.List;
     
    1817import java.util.Set;
    1918import java.util.function.Predicate;
     19import java.util.stream.Collectors;
    2020
    2121import javax.swing.JTree;
     
    3636import org.openstreetmap.josm.gui.util.GuiHelper;
    3737import org.openstreetmap.josm.tools.Destroyable;
    38 import org.openstreetmap.josm.tools.MultiMap;
     38import org.openstreetmap.josm.tools.ListenerList;
    3939
    4040/**
     
    7373    private transient Set<? extends OsmPrimitive> filter;
    7474
    75     /** a counter to check if tree has been rebuild */
    76     private int updateCount;
     75    private final ListenerList<Runnable> invalidationListeners = ListenerList.create();
    7776
    7877    /**
     
    135134        }
    136135        super.setVisible(v);
     136        invalidationListeners.fireEvent(Runnable::run);
    137137    }
    138138
     
    141141     */
    142142    public void buildTree() {
    143         updateCount++;
    144143        final DefaultMutableTreeNode rootNode = new DefaultMutableTreeNode();
    145144
     
    172171        }
    173172
    174         Map<Severity, MultiMap<String, TestError>> errorTree = new EnumMap<>(Severity.class);
    175         Map<Severity, HashMap<String, MultiMap<String, TestError>>> errorTreeDeep = new EnumMap<>(Severity.class);
    176         for (Severity s : Severity.values()) {
    177             errorTree.put(s, new MultiMap<String, TestError>(20));
    178             errorTreeDeep.put(s, new HashMap<String, MultiMap<String, TestError>>());
    179         }
    180 
    181         final Boolean other = ValidatorPreference.PREF_OTHER.get();
    182         for (TestError e : errors) {
    183             if (e.isIgnored()) {
    184                 continue;
    185             }
    186             Severity s = e.getSeverity();
    187             if (!other && s == Severity.OTHER) {
    188                 continue;
    189             }
    190             String d = e.getDescription();
    191             String m = e.getMessage();
    192             if (filter != null) {
    193                 boolean found = false;
    194                 for (OsmPrimitive p : e.getPrimitives()) {
    195                     if (filter.contains(p)) {
    196                         found = true;
    197                         break;
    198                     }
    199                 }
    200                 if (!found) {
    201                     continue;
    202                 }
    203             }
    204             if (d != null) {
    205                 MultiMap<String, TestError> b = errorTreeDeep.get(s).get(m);
    206                 if (b == null) {
    207                     b = new MultiMap<>(20);
    208                     errorTreeDeep.get(s).put(m, b);
    209                 }
    210                 b.put(d, e);
    211             } else {
    212                 errorTree.get(s).put(m, e);
    213             }
    214         }
     173        Predicate<TestError> filterToUse = e -> !e.isIgnored();
     174        if (!ValidatorPreference.PREF_OTHER.get()) {
     175            filterToUse = filterToUse.and(e -> e.getSeverity() != Severity.OTHER);
     176        }
     177        if (filter != null) {
     178            filterToUse = filterToUse.and(e -> e.getPrimitives().stream().anyMatch(filter::contains));
     179        }
     180        Map<Severity, Map<String, Map<String, List<TestError>>>> errorTreeDeep
     181            = errors.stream().filter(filterToUse).collect(
     182                    Collectors.groupingBy(e -> e.getSeverity(), () -> new EnumMap<>(Severity.class),
     183                            Collectors.groupingBy(e -> e.getDescription() == null ? "" : e.getDescription(),
     184                                    Collectors.groupingBy(e -> e.getMessage()))));
    215185
    216186        List<TreePath> expandedPaths = new ArrayList<>();
    217         for (Severity s : Severity.values()) {
    218             MultiMap<String, TestError> severityErrors = errorTree.get(s);
    219             Map<String, MultiMap<String, TestError>> severityErrorsDeep = errorTreeDeep.get(s);
    220             if (severityErrors.isEmpty() && severityErrorsDeep.isEmpty()) {
    221                 continue;
    222             }
    223 
     187        errorTreeDeep.forEach((s, severityErrorsDeep) -> {
    224188            // Severity node
    225189            DefaultMutableTreeNode severityNode = new GroupTreeNode(s);
     
    230194            }
    231195
    232             for (Entry<String, Set<TestError>> msgErrors : severityErrors.entrySet()) {
    233                 // Message node
    234                 Set<TestError> errs = msgErrors.getValue();
    235                 String msg = tr("{0} ({1})", msgErrors.getKey(), errs.size());
    236                 DefaultMutableTreeNode messageNode = new DefaultMutableTreeNode(msg);
    237                 severityNode.add(messageNode);
    238 
    239                 if (oldSelectedRows.contains(msgErrors.getKey())) {
    240                     expandedPaths.add(new TreePath(new Object[] {rootNode, severityNode, messageNode}));
    241                 }
    242 
    243                 for (TestError error : errs) {
    244                     // Error node
    245                     DefaultMutableTreeNode errorNode = new DefaultMutableTreeNode(error);
    246                     messageNode.add(errorNode);
    247                 }
    248             }
    249             for (Entry<String, MultiMap<String, TestError>> bag : severityErrorsDeep.entrySet()) {
     196            Map<String, List<TestError>> severityErrors = severityErrorsDeep.get("");
     197            if (severityErrors != null) {
     198                for (Entry<String, List<TestError>> msgErrors : severityErrors.entrySet()) {
     199                    // Message node
     200                    List<TestError> errs = msgErrors.getValue();
     201                    String msg = tr("{0} ({1})", msgErrors.getKey(), errs.size());
     202                    DefaultMutableTreeNode messageNode = new DefaultMutableTreeNode(msg);
     203                    severityNode.add(messageNode);
     204
     205                    if (oldSelectedRows.contains(msgErrors.getKey())) {
     206                        expandedPaths.add(new TreePath(new Object[] {rootNode, severityNode, messageNode}));
     207                    }
     208
     209                    errs.stream().map(DefaultMutableTreeNode::new).forEach(messageNode::add);
     210                }
     211            }
     212
     213            severityErrorsDeep.forEach((description, errorlist) -> {
     214                if (description.isEmpty()) {
     215                    return;
     216                }
    250217                // Group node
    251                 MultiMap<String, TestError> errorlist = bag.getValue();
    252                 DefaultMutableTreeNode groupNode = null;
     218                DefaultMutableTreeNode groupNode;
    253219                if (errorlist.size() > 1) {
    254                     groupNode = new GroupTreeNode(bag.getKey());
     220                    groupNode = new GroupTreeNode(description);
    255221                    severityNode.add(groupNode);
    256                     if (oldSelectedRows.contains(bag.getKey())) {
     222                    if (oldSelectedRows.contains(description)) {
    257223                        expandedPaths.add(new TreePath(new Object[] {rootNode, severityNode, groupNode}));
    258224                    }
    259                 }
    260 
    261                 for (Entry<String, Set<TestError>> msgErrors : errorlist.entrySet()) {
     225                } else {
     226                    groupNode = null;
     227                }
     228
     229                errorlist.forEach((message, errs) -> {
    262230                    // Message node
    263                     Set<TestError> errs = msgErrors.getValue();
    264231                    String msg;
    265232                    if (groupNode != null) {
    266                         msg = tr("{0} ({1})", msgErrors.getKey(), errs.size());
     233                        msg = tr("{0} ({1})", message, errs.size());
    267234                    } else {
    268                         msg = tr("{0} - {1} ({2})", msgErrors.getKey(), bag.getKey(), errs.size());
     235                        msg = tr("{0} - {1} ({2})", message, description, errs.size());
    269236                    }
    270237                    DefaultMutableTreeNode messageNode = new DefaultMutableTreeNode(msg);
     
    275242                    }
    276243
    277                     if (oldSelectedRows.contains(msgErrors.getKey())) {
     244                    if (oldSelectedRows.contains(message)) {
    278245                        if (groupNode != null) {
    279246                            expandedPaths.add(new TreePath(new Object[] {rootNode, severityNode, groupNode, messageNode}));
     
    283250                    }
    284251
    285                     for (TestError error : errs) {
    286                         // Error node
    287                         DefaultMutableTreeNode errorNode = new DefaultMutableTreeNode(error);
    288                         messageNode.add(errorNode);
    289                     }
    290                 }
    291             }
    292         }
     252                    errs.stream().map(DefaultMutableTreeNode::new).forEach(messageNode::add);
     253                });
     254            });
     255        });
    293256
    294257        valTreeModel.setRoot(rootNode);
     
    296259            this.expandPath(path);
    297260        }
     261
     262        invalidationListeners.fireEvent(Runnable::run);
     263    }
     264
     265    /**
     266     * Add a new invalidation listener
     267     * @param listener The listener
     268     */
     269    public void addInvalidationListener(Runnable listener) {
     270        invalidationListeners.addListener(listener);
     271    }
     272
     273    /**
     274     * Remove an invalidation listener
     275     * @param listener The listener
     276     * @since 10880
     277     */
     278    public void removeInvalidationListener(Runnable listener) {
     279        invalidationListeners.removeListener(listener);
    298280    }
    299281
     
    426408    }
    427409
    428     /**
    429      * Returns a value to check if tree has been rebuild
    430      * @return the current counter
    431      */
    432     public int getUpdateCount() {
    433         return updateCount;
    434     }
    435 
    436410    private void clearErrors() {
    437411        if (errors != null) {
Note: See TracChangeset for help on using the changeset viewer.