Statistics
| Revision:

gvsig-projects-pool / org.gvsig.topology / trunk / org.gvsig.topology / org.gvsig.topology.swing / org.gvsig.topology.swing.impl / src / main / java / org / gvsig / topology / swing / impl / DefaultJTopologyReport.java @ 760

History | View | Annotate | Download (26.5 KB)

1
package org.gvsig.topology.swing.impl;
2

    
3
import java.awt.BorderLayout;
4
import java.awt.Dimension;
5
import java.awt.event.ActionEvent;
6
import java.awt.event.ActionListener;
7
import java.awt.event.MouseAdapter;
8
import java.awt.event.MouseEvent;
9
import java.net.URL;
10
import java.util.ArrayList;
11
import java.util.HashSet;
12
import java.util.List;
13
import java.util.Set;
14
import javax.swing.DefaultComboBoxModel;
15
import javax.swing.DefaultListSelectionModel;
16
import javax.swing.ImageIcon;
17
import javax.swing.JComponent;
18
import javax.swing.JMenuItem;
19
import javax.swing.JPopupMenu;
20
import javax.swing.JTable;
21
import javax.swing.ListSelectionModel;
22
import javax.swing.SwingUtilities;
23
import javax.swing.event.ChangeEvent;
24
import javax.swing.event.ChangeListener;
25
import javax.swing.event.ListSelectionEvent;
26
import javax.swing.event.ListSelectionListener;
27
import javax.swing.event.TableModelEvent;
28
import javax.swing.event.TableModelListener;
29
import javax.swing.table.TableModel;
30
import org.apache.commons.io.FilenameUtils;
31
import org.apache.commons.lang3.StringUtils;
32
import org.gvsig.expressionevaluator.ExpressionBuilder;
33
import org.gvsig.expressionevaluator.ExpressionEvaluatorLocator;
34
import org.gvsig.fmap.dal.feature.FeatureSelection;
35
import org.gvsig.fmap.geom.Geometry;
36
import org.gvsig.fmap.geom.primitive.Envelope;
37
import org.gvsig.tools.ToolsLocator;
38
import org.gvsig.tools.dynform.DynFormLocator;
39
import org.gvsig.tools.dynform.JDynForm;
40
import org.gvsig.tools.dynobject.DynObject;
41
import org.gvsig.tools.i18n.I18nManager;
42
import org.gvsig.tools.observer.Observable;
43
import org.gvsig.tools.observer.Observer;
44
import org.gvsig.tools.swing.api.ListElement;
45
import org.gvsig.tools.swing.api.ToolsSwingLocator;
46
import org.gvsig.tools.swing.api.ToolsSwingManager;
47
import org.gvsig.tools.swing.api.task.TaskStatusController;
48
import org.gvsig.tools.swing.icontheme.IconTheme;
49
import org.gvsig.tools.task.TaskStatus;
50
import org.gvsig.topology.lib.api.TopologyLocator;
51
import org.gvsig.topology.lib.api.TopologyPlan;
52
import org.gvsig.topology.lib.api.TopologyReport;
53
import org.gvsig.topology.lib.api.TopologyReportLine;
54
import org.gvsig.topology.lib.api.TopologyReportLineSet;
55
import org.gvsig.topology.lib.api.TopologyRule;
56
import org.gvsig.topology.lib.api.TopologyRuleAction;
57
import org.gvsig.topology.lib.api.TopologyRuleFactory;
58
import org.gvsig.topology.swing.api.JTopologyReport;
59
import org.gvsig.topology.swing.api.TopologySwingLocator;
60
import org.gvsig.topology.swing.api.TopologySwingServices;
61
import org.gvsig.topology.swing.api.TopologySwingServices.WorkingAreaChangedListener;
62
import org.slf4j.Logger;
63
import org.slf4j.LoggerFactory;
64

    
65
/**
66
 *
67
 * @author jjdelcerro
68
 */
69
@SuppressWarnings("UseSpecificCatch")
70
public class DefaultJTopologyReport
71
        extends DefaultJTopologyReportView
72
        implements JTopologyReport {
73

    
74
    private static final Logger LOGGER = LoggerFactory.getLogger(DefaultJTopologyReport.class);
75
    private ListSelectionModel selection;
76

    
77
    private class TopologyRuleActionParametersListener implements ActionListener {
78

    
79
        private final TopologyRule rule;
80
        private final List<TopologyReportLine> lines;
81
        private final TopologyRuleAction action;
82
        private final JDynForm form;
83

    
84
        public TopologyRuleActionParametersListener(
85
                TopologyRule rule,
86
                List<TopologyReportLine> lines,
87
                TopologyRuleAction action,
88
                JDynForm form
89
        ) {
90
            this.action = action;
91
            this.lines = lines;
92
            this.rule = rule;
93
            this.form = form;
94
        }
95

    
96
        @Override
97
        public void actionPerformed(ActionEvent e) {
98
            doExecuteRuleAction(rule, lines, action, form);
99
        }
100
    }
101

    
102
    private class TopologyRuleActionListener implements ActionListener {
103

    
104
        private final TopologyRule rule;
105
        private final List<TopologyReportLine> lines;
106
        private final TopologyRuleAction action;
107

    
108
        public TopologyRuleActionListener(
109
                TopologyRule rule,
110
                List<TopologyReportLine> lines,
111
                TopologyRuleAction action
112
        ) {
113
            this.action = action;
114
            this.lines = lines;
115
            this.rule = rule;
116
        }
117

    
118
        @Override
119
        public void actionPerformed(ActionEvent e) {
120
            if (this.action.hasParameters()) {
121
                doShowActionParametersPanel(this.rule, this.lines, this.action);
122
            } else {
123
                doExecuteRuleAction(rule, lines, action, null);
124
            }
125
        }
126
    }
127

    
128
    private ReportTable linesModel;
129
    private final TopologySwingServices services;
130
    private TaskStatusController taskStatusController;
131
    private TopologyPlan plan;
132
    private WorkingAreaChangedListener workingAreaChangedListener;
133

    
134
    public DefaultJTopologyReport(TopologyPlan plan) {
135
        this.services = TopologySwingLocator.getTopologySwingManager().getDefaultServices();
136
        this.initComponents();
137
    }
138

    
139
    private void initComponents() {
140
        I18nManager i18n = ToolsLocator.getI18nManager();
141
        this.selection = this.tblErrors.getSelectionModel();
142
        this.linesModel = new ReportTable();
143

    
144
        this.workingAreaChangedListener = new WorkingAreaChangedListener() {
145
            @Override
146
            public void workingAreaChanged(Envelope workingArea) {
147
                doUpdateFilter();
148
            }
149
        };
150
        this.tblErrors.setModel(this.linesModel);
151
        this.tblErrors.setAutoResizeMode(JTable.AUTO_RESIZE_LAST_COLUMN);
152

    
153
        this.btnZoomGeometry.addActionListener(new ActionListener() {
154
            @Override
155
            public void actionPerformed(ActionEvent e) {
156
                doZoomGeometry();
157
            }
158
        });
159
        this.btnZoomError.addActionListener(new ActionListener() {
160
            @Override
161
            public void actionPerformed(ActionEvent e) {
162
                doZoomError();
163
            }
164
        });
165
        this.btnCenterGeometry.addActionListener(new ActionListener() {
166
            @Override
167
            public void actionPerformed(ActionEvent e) {
168
                doCenterGeometry();
169
            }
170
        });
171
        this.btnCenterError.addActionListener(new ActionListener() {
172
            @Override
173
            public void actionPerformed(ActionEvent e) {
174
                doCenterError();
175
            }
176
        });
177
        this.btnRefresh.addActionListener(new ActionListener() {
178
            @Override
179
            public void actionPerformed(ActionEvent e) {
180
                doExecutePlan();
181
            }
182
        });
183
        this.tblErrors.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
184
            @Override
185
            public void valueChanged(ListSelectionEvent e) {
186
                doRowSelected();
187
            }
188
        });
189
        this.tblErrors.addMouseListener(new MouseAdapter() {
190
            @Override
191
            public void mouseClicked(MouseEvent e) {
192
                if (e.getButton() == MouseEvent.BUTTON1 && e.getClickCount() == 2) {
193
                    doCenterError();
194
                }
195
            }
196
        });
197

    
198
        this.btnActions.addActionListener(new ActionListener() {
199
            @Override
200
            public void actionPerformed(ActionEvent e) {
201
                doSelectAction();
202
            }
203
        });
204
        this.btnParametersCancel.addActionListener(new ActionListener() {
205
            @Override
206
            public void actionPerformed(ActionEvent e) {
207
                tabData.setEnabledAt(0, true);
208
                tabData.setEnabledAt(1, false);
209
                tabData.setSelectedIndex(0);
210
                pnlParameters.removeAll();
211
            }
212
        });
213
        this.btnShowErrors.addActionListener(new ActionListener() {
214
            @Override
215
            public void actionPerformed(ActionEvent e) {
216
                doUpdateFilter();
217
            }
218
        });
219
        this.btnShowExceptions.addActionListener(new ActionListener() {
220
            @Override
221
            public void actionPerformed(ActionEvent e) {
222
                doUpdateFilter();
223
            }
224
        });
225
        this.btnVisibleExtentOnly.addActionListener(new ActionListener() {
226
            @Override
227
            public void actionPerformed(ActionEvent e) {
228
                doUpdateFilter();
229
            }
230
        });
231
        this.btnShowForm.addActionListener(new ActionListener() {
232
            @Override
233
            public void actionPerformed(ActionEvent e) {
234
                services.setShowFormWhenEdit(btnShowForm.isSelected());
235
            }
236
        });
237
        this.btnEraseErrorMarks.addActionListener(new ActionListener() {
238
            @Override
239
            public void actionPerformed(ActionEvent e) {
240
                services.addError(null);
241
            }
242
        });
243
        DefaultComboBoxModel<ListElement<TopologyRuleFactory>> modelRules = new DefaultComboBoxModel<>();
244
        modelRules.addElement(new ListElement<>(i18n.getTranslation("_Any_rule"), (TopologyRuleFactory) null));
245
        List<TopologyRuleFactory> factories = TopologyLocator.getTopologyManager().getRuleFactories();
246
        for (TopologyRuleFactory factory : factories) {
247
            modelRules.addElement(new ListElement<>(factory.getName(), factory));
248
        }
249
        this.cboRules.setModel(modelRules);
250
        this.cboRules.addActionListener(new ActionListener() {
251
            @Override
252
            public void actionPerformed(ActionEvent e) {
253
                // Llama al invokeLater para poder debugguear
254
                SwingUtilities.invokeLater(new Runnable() {
255
                    @Override
256
                    public void run() {
257
                        doUpdateFilter();
258
                    }
259
                });
260
            }
261
        });
262
        this.taskStatusController = ToolsSwingLocator.getTaskStatusSwingManager().createTaskStatusController(
263
                null,
264
                this.lblTaskStatusTitle,
265
                this.lblTaskStatusMessage,
266
                this.pbTaskStatusProgress,
267
                this.btnTaskStatusCancel,
268
                null
269
        );
270
        this.translate();
271
        this.setPreferredSize(new Dimension(700, 200));
272

    
273
        this.btnShowErrors.setSelected(false);
274
        this.btnShowExceptions.setSelected(false);
275
        this.btnVisibleExtentOnly.setSelected(false);
276

    
277
        this.tabData.setEnabledAt(1, false);
278

    
279
    }
280

    
281
    @Override
282
    public ImageIcon loadImage(String imageName) {
283
        String name = FilenameUtils.getBaseName(imageName);
284
        IconTheme theme = ToolsSwingLocator.getIconThemeManager().getDefault();
285
        if (theme.exists(name)) {
286
            return theme.get(name);
287
        }
288
        URL url = this.getClass().getResource("/" + imageName);
289
        if (url == null) {
290
            return null;
291
        }
292
        return new ImageIcon(url);
293
    }
294

    
295
    private void translate() {
296
        ToolsSwingManager tsm = ToolsSwingLocator.getToolsSwingManager();
297
        tsm.translate(this.btnActions);
298
        tsm.translate(this.btnCenterError);
299
        tsm.translate(this.btnCenterGeometry);
300
        tsm.translate(this.btnRefresh);
301
        tsm.translate(this.btnShowErrors);
302
        tsm.translate(this.btnShowExceptions);
303
        tsm.translate(this.btnZoomError);
304
        tsm.translate(this.btnZoomGeometry);
305
        tsm.translate(this.btnEraseErrorMarks);
306
        tsm.translate(this.btnVisibleExtentOnly);
307
        tsm.translate(this.btnParametersAccept);
308
        tsm.translate(this.btnParametersCancel);
309
        tsm.translate(this.btnShowForm);
310
        tsm.translate(this.lblShow);
311
        tsm.translate(this.tabData);
312
    }
313

    
314
    @Override
315
    public void put(TopologyPlan plan) {
316
        this.plan = plan;
317
        this.taskStatusController.bind(this.plan.getTaskStatus());
318
        this.plan.getTaskStatus().addObserver(new Observer() {
319
            @Override
320
            public void update(Observable o, Object o1) {
321
                doTaskStatusUpdated(o, o1);
322
            }
323
        });
324
        this.linesModel.setReport(plan.getReport());
325
    }
326

    
327
    @Override
328
    public JComponent asJComponent() {
329
        return this;
330
    }
331

    
332
    private void doUpdateFilter() {
333
        this.linesModel.setFilter(this.getFilter());
334
    }
335

    
336
    private String getFilter() {
337
        ExpressionBuilder builder = ExpressionEvaluatorLocator.getManager().createExpressionBuilder();
338
        TopologyRuleFactory ruleFactory = (TopologyRuleFactory) ListElement.getSelected(cboRules);
339
        if (ruleFactory != null) {
340
            builder.setValue(
341
                    builder.eq(
342
                            builder.column(TopologyReport.RULE_ID),
343
                            builder.constant(ruleFactory.getId())
344
                    )
345
            );
346
        }
347
        if (this.btnShowErrors.isSelected()) {
348
            if (btnShowExceptions.isSelected()) {
349
                builder.and(
350
                        builder.or(
351
                                builder.column(TopologyReport.IS_ERROR),
352
                                builder.column(TopologyReport.IS_EXCEPTION)
353
                        )
354
                );
355
            } else {
356
                builder.and(
357
                        builder.column(TopologyReport.IS_ERROR)
358
                );
359
            }
360
        } else if (btnShowExceptions.isSelected()) {
361
            builder.and(
362
                    builder.column(TopologyReport.IS_EXCEPTION)
363
            );
364
        }
365
        if (this.btnVisibleExtentOnly.isSelected()) {
366
            Envelope workingArea = this.services.getWorkingArea();
367
            if (workingArea != null) {
368
                builder.and(
369
                        builder.ST_Intersects(
370
                                builder.column(TopologyReport.GEOMETRY),
371
                                builder.geometry(workingArea.getGeometry())
372
                        )
373
                );
374
            }
375
            this.services.addWorkingAreaChangedListener(this.workingAreaChangedListener);
376
        } else {
377
            this.services.removeWorkingAreaChangedListener(this.workingAreaChangedListener);
378
        }
379
        if (builder.getValue() == null) {
380
            return null;
381
        }
382
        return builder.toString();
383
    }
384

    
385
    private void doExecutePlan() {
386
        Thread th = new Thread(new Runnable() {
387
            @Override
388
            public void run() {
389
                plan.execute();
390
            }
391
        }, "TopologyPlan-" + plan.getName());
392
        th.start();
393
    }
394

    
395
    private void doTaskStatusUpdated(final Observable observable, final Object notification) {
396
        if (observable != null && !(observable instanceof TaskStatus)) {
397
            return;
398
        }
399
        if (!SwingUtilities.isEventDispatchThread()) {
400
            SwingUtilities.invokeLater(new Runnable() {
401
                public void run() {
402
                    doTaskStatusUpdated(observable, notification);
403
                }
404
            });
405
            return;
406
        }
407
        TaskStatus taskStatus = (TaskStatus) observable;
408
        if (taskStatus == null || !taskStatus.isRunning()) {
409
            this.lblTaskStatusTitle.setVisible(false);
410
            this.lblTaskStatusMessage.setVisible(false);
411
            this.pbTaskStatusProgress.setVisible(false);
412
            this.btnTaskStatusCancel.setVisible(false);
413
            this.btnRefresh.setEnabled(true);
414
            I18nManager i18n = ToolsLocator.getI18nManager();
415
            message(i18n.getTranslation("_Errors") + ": " + this.linesModel.getRowCount());
416
            return;
417
        }
418
        if (!this.pbTaskStatusProgress.isVisible()) {
419
            this.lblTaskStatusTitle.setVisible(true);
420
            this.lblTaskStatusMessage.setVisible(true);
421
            this.pbTaskStatusProgress.setVisible(true);
422
            this.btnTaskStatusCancel.setVisible(true);
423
            this.btnRefresh.setEnabled(false);
424
        }
425
    }
426

    
427
    private void message(String msg) {
428
        this.lblTaskStatusTitle.setText(msg);
429
        this.lblTaskStatusTitle.setVisible(true);
430
    }
431

    
432
    private void doSelectAction() {
433
        int n = this.tblErrors.getSelectedRow();
434
        if (n < 0) {
435
            return;
436
        }
437
        int[] selectedRows = this.tblErrors.getSelectedRows();
438
        TopologyRule rule = this.linesModel.getLine(selectedRows[0]).getRule();
439
        List<TopologyRuleAction> actions = rule.getActions();
440
        if (actions == null || actions.isEmpty()) {
441
            return;
442
        }
443
        List<TopologyReportLine> lines = new ArrayList<>();
444
        for (int selectedRow : selectedRows) {
445
            TopologyReportLine line = this.linesModel.getLine(selectedRow);
446
            if (line.getRule() == rule) {
447
                lines.add(line);
448
            }
449
        }
450
        JPopupMenu menu = new JPopupMenu();
451
        for (TopologyRuleAction action : actions) {
452
            JMenuItem item;
453
            if (action.hasParameters()) {
454
                item = new JMenuItem(action.getName() + "...");
455
            } else {
456
                item = new JMenuItem(action.getName());
457
            }
458
            item.addActionListener(new TopologyRuleActionListener(rule, lines, action));
459
            if (lines.size() > 1 && action.hasParameters()) {
460
                item.setEnabled(false);
461
            }
462
            menu.add(item);
463
        }
464
        menu.show(this.btnActions, 0, this.btnActions.getHeight());
465
    }
466

    
467
    private void doExecuteRuleAction(
468
            TopologyRule rule,
469
            List<TopologyReportLine> lines,
470
            TopologyRuleAction action,
471
            JDynForm form
472
    ) {
473
        DynObject parameters = null;
474
        if (form != null) {
475
            parameters = action.createParameters();
476
            if (parameters != null) {
477
                form.getValues(parameters);
478
            }
479
        }
480
        for (TopologyReportLine line : lines) {
481
            action.execute(rule, line, parameters);
482
        }
483
        this.tabData.setEnabledAt(0, true);
484
        this.tabData.setEnabledAt(1, false);
485
        this.tabData.setSelectedIndex(0);
486
        this.pnlParameters.removeAll();
487
        this.services.addError(null);
488
    }
489

    
490
    private void doShowActionParametersPanel(
491
            TopologyRule rule,
492
            List<TopologyReportLine> lines,
493
            TopologyRuleAction action
494
    ) {
495
        I18nManager i18n = ToolsLocator.getI18nManager();
496
        this.tabData.setEnabledAt(0, false);
497
        this.tabData.setEnabledAt(1, true);
498
        this.tabData.setSelectedIndex(1);
499

    
500
        try {
501
            JDynForm form = null;
502
            this.lblActionTitle.setText(
503
                    "<html>"
504
                    + i18n.getTranslation("_Rule") + ": <b>"
505
                    + rule.getName() + "</b>, "
506
                    + i18n.getTranslation("_Action") + ": <b>"
507
                    + action.getName() + "</b></html>"
508
            );
509
            this.lblActionDescription.setText("<html>" + action.getShortDescription() + "</html>");
510
            DynObject parameters = action.createParameters();
511
            if (parameters != null) {
512
                form = DynFormLocator.getDynFormManager().createJDynForm(parameters);
513
                if (form != null) {
514
                    this.pnlParameters.setLayout(new BorderLayout());
515
                    this.pnlParameters.removeAll();
516
                    this.pnlParameters.add(form.asJComponent(), BorderLayout.CENTER);
517
                    this.pnlParameters.revalidate();
518
                    this.pnlParameters.repaint();
519
                }
520
            }
521
            this.btnParametersAccept.addActionListener(
522
                    new TopologyRuleActionParametersListener(rule, lines, action, form)
523
            );
524
        } catch (Exception ex) {
525
            LOGGER.warn("Can't show action parameters panel.", ex);
526
        }
527
    }
528

    
529
    private void doZoomGeometry() {
530
        int n = this.tblErrors.getSelectedRow();
531
        if (n < 0) {
532
            return;
533
        }
534
        TopologyReportLine line = this.linesModel.getLine(n);
535
        Geometry geom = line.getGeometry();
536
        this.services.zoomTo(geom.getEnvelope());
537
    }
538

    
539
    private void doZoomError() {
540
        int n = this.tblErrors.getSelectedRow();
541
        if (n < 0) {
542
            return;
543
        }
544
        TopologyReportLine line = this.linesModel.getLine(n);
545
        Geometry geom = line.getError();
546
        if (geom == null) {
547
            geom = line.getGeometry();
548
            services.addError(null);
549
        } else {
550
            services.addError(geom);
551
        }
552
        this.services.zoomTo(geom.getEnvelope());
553
    }
554

    
555
    private void doCenterGeometry() {
556
        try {
557
            int n = this.tblErrors.getSelectedRow();
558
            if (n < 0) {
559
                return;
560
            }
561
            TopologyReportLine line = this.linesModel.getLine(n);
562
            Geometry geom = line.getGeometry();
563
            this.services.centerTo(geom.centroid());
564
        } catch (Exception ex) {
565
            LOGGER.warn("Can't center topology error", ex);
566
        }
567
    }
568

    
569
    private void doCenterError() {
570
        try {
571
            int n = this.tblErrors.getSelectedRow();
572
            if (n < 0) {
573
                return;
574
            }
575
            TopologyReportLine line = this.linesModel.getLine(n);
576
            Geometry geom = line.getError();
577
            if (geom == null) {
578
                geom = line.getGeometry();
579
                services.addError(null);
580
            } else {
581
                services.addError(geom);
582
            }
583
            this.services.centerTo(geom.centroid());
584
        } catch (Exception ex) {
585
            LOGGER.warn("Can't center topology error", ex);
586
        }
587
    }
588

    
589
    private void doRowSelected() {
590
        try {
591
            int n = this.tblErrors.getSelectedRow();
592
            if (n < 0) {
593
                return;
594
            }
595
            TopologyReportLine line = this.linesModel.getLine(n);
596
            if (line.getFeature1() == null) {
597
                return;
598
            }
599
            this.services.addError(null);
600
            FeatureSelection selection = line.getDataSet1().getFeatureStore().getFeatureSelection();
601
            selection.deselectAll();
602
            selection.select(line.getFeature1());
603
        } catch (Exception ex) {
604
            LOGGER.warn("Can't select topology error", ex);
605
        }
606
    }
607

    
608
    private class ReportTable implements TableModel {
609

    
610
        private TopologyReport report;
611
        private TopologyReportLineSet lines;
612
        private final String[] columnNames;
613
        private final Class[] columnClasses;
614
        private final Set<TableModelListener> tableListeners;
615
        private final ChangeListener reportListener;
616
        private String lastFilter;
617

    
618
        public ReportTable() {
619
            I18nManager i18n = ToolsLocator.getI18nManager();
620
            this.report = null;
621
            this.lines = null;
622
            this.tableListeners = new HashSet<>();
623
            this.columnNames = new String[]{
624
                i18n.getTranslation("_Rule"),
625
                i18n.getTranslation("_Dataset1"),
626
                i18n.getTranslation("_Dataset2"),
627
                i18n.getTranslation("_Exception"),
628
                i18n.getTranslation("_Description")
629
            };
630
            this.columnClasses = new Class[]{
631
                String.class,
632
                String.class,
633
                String.class,
634
                Boolean.class,
635
                String.class
636
            };
637
            this.reportListener = new ChangeListener() {
638
                @Override
639
                public void stateChanged(final ChangeEvent e) {
640
                    if (!SwingUtilities.isEventDispatchThread()) {
641
                        SwingUtilities.invokeLater(new Runnable() {
642
                            @Override
643
                            public void run() {
644
                                stateChanged(e);
645
                            }
646
                        });
647
                        return;
648
                    }
649
                    fireTableChanged();
650
                }
651
            };
652
        }
653

    
654
        public void setReport(TopologyReport report) {
655
            if (this.report != null) {
656
                this.report.removeChangeListener(this.reportListener);
657
            }
658
            this.report = report;
659
            this.lines = this.report;
660
            this.lines.addChangeListener(this.reportListener);
661
        }
662

    
663
        public void setFilter(String filter) {
664
            if (StringUtils.equals(filter, this.lastFilter)) {
665
                return;
666
            }
667
            this.lines = this.report.getLineSet(filter);
668
            this.lines.addChangeListener(this.reportListener);
669
            this.lastFilter = filter;
670
            this.fireTableChanged();
671
        }
672

    
673
        public TopologyReport getReport() {
674
            return this.report;
675
        }
676

    
677
        @Override
678
        public int getRowCount() {
679
            if (this.lines == null) {
680
                return 0;
681
            }
682
            return this.lines.size();
683
        }
684

    
685
        @Override
686
        public int getColumnCount() {
687
            return 5;
688
        }
689

    
690
        @Override
691
        public String getColumnName(int columnIndex) {
692
            return this.columnNames[columnIndex];
693
        }
694

    
695
        @Override
696
        public Class<?> getColumnClass(int columnIndex) {
697
            return this.columnClasses[columnIndex];
698
        }
699

    
700
        @Override
701
        public boolean isCellEditable(int rowIndex, int columnIndex) {
702
            return false;
703
        }
704

    
705
        @Override
706
        public Object getValueAt(int rowIndex, int columnIndex) {
707
            if (this.lines == null) {
708
                return "";
709
            }
710
            TopologyReportLine line = this.lines.get(rowIndex);
711
            switch (columnIndex) {
712
                case 0:
713
                    return line.getRule().getName();
714
                case 1:
715
                    return line.getDataSet1().getName();
716
                case 2:
717
                    if (line.getDataSet2() == null) {
718
                        return "";
719
                    }
720
                    return line.getDataSet2().getName();
721
                case 3:
722
                    return line.isException();
723
                case 4:
724
                    return line.getDescription();
725
                default:
726
                    return "???";
727
            }
728
        }
729

    
730
        @Override
731
        public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
732
        }
733

    
734
        @Override
735
        public void addTableModelListener(TableModelListener l) {
736
            this.tableListeners.add(l);
737
        }
738

    
739
        @Override
740
        public void removeTableModelListener(TableModelListener l) {
741
            this.tableListeners.remove(l);
742
        }
743

    
744
        private void fireTableChanged() {
745
            saveCurrentSelection();
746
            for (TableModelListener tableListener : this.tableListeners) {
747
                tableListener.tableChanged(new TableModelEvent(this));
748
            }
749
            restoreCurrentSelection();
750
        }
751

    
752
        public TopologyReportLine getLine(int lineNum) {
753
            return this.lines.get(lineNum);
754
        }
755

    
756
    }
757

    
758
    private void saveCurrentSelection() {
759
        this.tblErrors.setSelectionModel(new DefaultListSelectionModel());
760
    }
761

    
762
    private void restoreCurrentSelection() {
763
        this.tblErrors.setSelectionModel(this.selection);
764
    }
765
}