001package jmri.jmrit.beantable;
002
003import java.awt.BorderLayout;
004import java.awt.Component;
005import java.awt.Frame;
006import java.awt.event.ActionEvent;
007import java.awt.event.ActionListener;
008import java.text.MessageFormat;
009import java.util.*;
010
011import javax.swing.*;
012
013import javax.annotation.*;
014
015import jmri.*;
016import jmri.jmrit.blockboss.BlockBossLogic;
017import jmri.jmrit.blockboss.BlockBossLogicProvider;
018import jmri.jmrit.display.*;
019import jmri.jmrit.display.layoutEditor.LayoutBlock;
020import jmri.jmrit.display.layoutEditor.LayoutBlockManager;
021import jmri.jmrit.logix.OBlock;
022import jmri.jmrit.logix.OBlockManager;
023
024import jmri.jmrit.picker.PickListModel;
025
026import jmri.util.ThreadingUtil;
027
028import org.slf4j.Logger;
029import org.slf4j.LoggerFactory;
030
031/**
032 * A collection of static utilities to provide cross referencing information
033 * among the various PanelPro objects. Most likely, this is incomplete as there
034 * still may be references held by objects unknown to the author. It is intended
035 * to inform users where and how the various elements are used. In particular to
036 * identify useless elements ('orphans'). Currently, called only from the Logix
037 * JFrame, which is probably not its ultimate UI.
038 *
039 * @author Pete Cressman Copyright 2009
040 */
041public class Maintenance {
042
043    static final ResourceBundle rbm = ResourceBundle.getBundle("jmri.jmrit.beantable.MaintenanceBundle");
044
045    /**
046     * Find references of a System or User name in the various Manager Objects.
047     *
048     * @param devName name to look for
049     * @param parent Frame calling this method
050     */
051    public static void deviceReportPressed(String devName, Frame parent) {
052        JTextArea text = new javax.swing.JTextArea(25, 50);
053        text.setEditable(false);
054        text.setTabSize(4);
055        search(devName, text);
056        JScrollPane scrollPane = new JScrollPane(text);
057        makeDialog(scrollPane, null, parent, rbm.getString("CrossReferenceTitle"));
058    }
059    
060    /**
061     * get a String List of System Names for a given manager.
062     * <p>
063     * This is NOT a live list, so has to be called each time through.
064     * Do NOT cache the result of this call for later use.
065     * <p>
066     * TODO: Ideally a future refactor will use the getNamedBeanSet directly.
067     * @param mgr the Manager to get the system names for.
068     * @return List of system names.
069     */
070    private static List<String> getSystemNameList(Manager<?> mgr) {
071        ArrayList<String> systemNameList = new ArrayList<>();
072        mgr.getNamedBeanSet().forEach(b -> systemNameList.add(b.getSystemName()));
073        return Collections.unmodifiableList(systemNameList);
074    }
075
076    /**
077     * Find orphaned elements in the various Manager Objects.
078     *
079     * @param parent Frame to check
080     */
081    public static void findOrphansPressed(Frame parent) {
082        List<String> display = new ArrayList<>();
083        List<String> names = new ArrayList<>();
084
085        for (String name : getSystemNameList(InstanceManager.sensorManagerInstance())) {
086            if (!search(name, null) && !name.equals("ISCLOCKRUNNING")) {
087                display.add(MessageFormat.format(rbm.getString("OrphanName"),
088                        (Object[]) getTypeAndNames(name)));
089                names.add(name);
090            }
091        }
092        for (String name : getSystemNameList(InstanceManager.turnoutManagerInstance())) {
093            if (!search(name, null)) {
094                display.add(MessageFormat.format(rbm.getString("OrphanName"),
095                        (Object[]) getTypeAndNames(name)));
096                names.add(name);
097            }
098        }
099        for (String name : getSystemNameList(InstanceManager.getDefault(SignalHeadManager.class))) {
100            if (!search(name, null)) {
101                display.add(MessageFormat.format(rbm.getString("OrphanName"),
102                        (Object[]) getTypeAndNames(name)));
103                names.add(name);
104            }
105        }
106        for (String name : getSystemNameList(InstanceManager.lightManagerInstance())) {
107            if (!search(name, null)) {
108                display.add(MessageFormat.format(rbm.getString("OrphanName"),
109                        (Object[]) getTypeAndNames(name)));
110                names.add(name);
111            }
112        }
113        for (String name : getSystemNameList(InstanceManager.getDefault(ConditionalManager.class))) {
114            if (!search(name, null)) {
115                display.add(MessageFormat.format(rbm.getString("OrphanName"),
116                        (Object[]) getTypeAndNames(name)));
117                names.add(name);
118            }
119        }
120        for (String name : getSystemNameList(InstanceManager.getDefault(SectionManager.class))) {
121            if (!search(name, null)) {
122                display.add(MessageFormat.format(rbm.getString("OrphanName"),
123                        (Object[]) getTypeAndNames(name)));
124                names.add(name);
125            }
126        }
127        for (String name : getSystemNameList(InstanceManager.getDefault(BlockManager.class))) {
128            if (!search(name, null)) {
129                display.add(MessageFormat.format(rbm.getString("OrphanName"),
130                        (Object[]) getTypeAndNames(name)));
131                names.add(name);
132            }
133        }
134        DefaultListModel<String> listModel = new DefaultListModel<>();
135        for (int i = 0; i < display.size(); i++) {
136            listModel.addElement(display.get(i));
137        }
138        JList<String> list = new JList<>(listModel);
139        list.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);
140
141        JButton button = new JButton(Bundle.getMessage("ButtonDelete"));
142        button.setToolTipText(rbm.getString("OrphanDeleteHint"));
143
144        class SearchListener implements ActionListener {
145
146            JList<String> list;
147            List<String> n;
148
149            SearchListener(JList<String> list, List<String> name) {
150                this.list = list;
151                this.n = name;
152            }
153
154            @Override
155            public void actionPerformed(ActionEvent e) {
156                int index = list.getMaxSelectionIndex();
157                if (index < 0) {
158                    javax.swing.JOptionPane.showMessageDialog(null,
159                            rbm.getString("OrphanDeleteHint"),
160                            rbm.getString("DeleteTitle"),
161                            javax.swing.JOptionPane.INFORMATION_MESSAGE);
162                    return;
163                }
164                int min = list.getMinSelectionIndex();
165                DefaultListModel<String> model = (DefaultListModel<String>) list.getModel();
166                while (index >= min) {
167                    String[] names = getTypeAndNames(n.get(index));
168                    if (names[0].equals("Sensor")) { // NOI18N
169                        Sensor s = InstanceManager.getDefault(SensorManager.class).getBySystemName(names[2]);
170                        if (s == null) {
171                            s = InstanceManager.getDefault(SensorManager.class).getBySystemName(names[1]);
172                        }
173                        if (s != null) {
174                            InstanceManager.getDefault(SensorManager.class).deregister(s);
175                        }
176                    } else if (names[0].equals("Turnout")) { // NOI18N
177                        Turnout t = InstanceManager.getDefault(TurnoutManager.class).getBySystemName(names[2]);
178                        if (t == null) {
179                            t = InstanceManager.getDefault(TurnoutManager.class).getBySystemName(names[1]);
180                        }
181                        if (t != null) {
182                            InstanceManager.getDefault(TurnoutManager.class).deregister(t);
183                        }
184                    } else if (names[0].equals("SignalHead")) { // NOI18N
185                        SignalHead sh = InstanceManager.getDefault(SignalHeadManager.class).getBySystemName(names[2]);
186                        if (sh == null) {
187                            sh = InstanceManager.getDefault(SignalHeadManager.class).getBySystemName(names[1]);
188                        }
189                        if (sh != null) {
190                            InstanceManager.getDefault(SignalHeadManager.class).deregister(sh);
191                        }
192                    } else if (names[0].equals("Light")) { // NOI18N
193                        Light l = InstanceManager.getDefault(LightManager.class).getBySystemName(names[2]);
194                        if (l == null) {
195                            l = InstanceManager.getDefault(LightManager.class).getBySystemName(names[1]);
196                        }
197                        if (l != null) {
198                            InstanceManager.getDefault(LightManager.class).deregister(l);
199                        }
200                    } else if (names[0].equals("Conditional")) { // NOI18N
201                        Conditional c = InstanceManager.getDefault(ConditionalManager.class).getBySystemName(names[2]);
202                        if (c == null) {
203                            c = InstanceManager.getDefault(ConditionalManager.class).getBySystemName(names[1]);
204                        }
205                        if (c != null) {
206                            InstanceManager.getDefault(ConditionalManager.class).deregister(c);
207                        }
208                    } else if (names[0].equals("Section")) { // NOI18N
209                        Section sec = InstanceManager.getDefault(SectionManager.class).getBySystemName(names[2]);
210                        if (sec == null) {
211                            sec = InstanceManager.getDefault(SectionManager.class).getBySystemName(names[1]);
212                        }
213                        if (sec != null) {
214                            InstanceManager.getDefault(SectionManager.class).deregister(sec);
215                        }
216                    } else if (names[0].equals("Block")) { // NOI18N
217                        Block b = InstanceManager.getDefault(BlockManager.class).getBySystemName(names[2]);
218                        if (b == null) {
219                            b = InstanceManager.getDefault(BlockManager.class).getBySystemName(names[1]);
220                        }
221                        if (b != null) {
222                            InstanceManager.getDefault(BlockManager.class).deregister(b);
223                        }
224                    }
225                    model.remove(index);
226                    n.remove(index);
227                    index--;
228                }
229                index++;
230                if (index >= model.getSize()) {
231                    index = model.getSize() - 1;
232                }
233                if (index >= 0) {
234                    list.setSelectedIndex(index);
235                }
236            }
237        }
238        JScrollPane scrollPane = new JScrollPane(list);
239        button.addActionListener(new SearchListener(list, names));
240        button.setMaximumSize(button.getPreferredSize());
241        makeDialog(scrollPane, button, parent, rbm.getString("OrphanTitle"));
242    }
243
244    /**
245     * Find useless Conditionals in the various Manager Objects.
246     *
247     * @param parent Frame to check
248     */
249    public static void findEmptyPressed(Frame parent) {
250        List<String> display = new ArrayList<>();
251        List<String> names = new ArrayList<>();
252
253        log.debug("findEmptyPressed");
254        Iterator<String> iter = getSystemNameList(InstanceManager.getDefault(ConditionalManager.class)).iterator();
255        ConditionalManager cm = InstanceManager.getDefault(ConditionalManager.class);
256        while (iter.hasNext()) {
257            String name = iter.next();
258            Conditional c = cm.getBySystemName(name);
259            if (c != null) {
260                List<ConditionalVariable> variableList = c.getCopyOfStateVariables();
261                if (variableList.isEmpty()) {
262                    String userName = c.getUserName();
263                    display.add(MessageFormat.format(rbm.getString("OrphanName"),
264                            new Object[]{"Conditional", userName, name}));
265                    names.add(name);
266                }
267            }
268        }
269        DefaultListModel<String> listModel = new DefaultListModel<>();
270        for (int i = 0; i < display.size(); i++) {
271            listModel.addElement(display.get(i));
272        }
273        JList<String> list = new JList<>(listModel);
274        list.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);
275
276        JButton button = new JButton(Bundle.getMessage("ButtonDelete"));
277        button.setToolTipText(rbm.getString("OrphanDeleteHint") + Bundle.getMessage("ButtonDelete"));
278
279        class EmptyListener implements ActionListener {
280
281            JList<String> list;
282            List<String> name;
283
284            EmptyListener(JList<String> list, List<String> name) {
285                this.list = list;
286                this.name = name;
287            }
288
289            @Override
290            public void actionPerformed(ActionEvent e) {
291                int index = list.getMaxSelectionIndex();
292                if (index < 0) {
293                    javax.swing.JOptionPane.showMessageDialog(null,
294                            rbm.getString("OrphanDeleteHint"),
295                            rbm.getString("DeleteTitle"),
296                            javax.swing.JOptionPane.INFORMATION_MESSAGE);
297                    return;
298                }
299                int min = list.getMinSelectionIndex();
300                DefaultListModel<String> model = (DefaultListModel<String>) list.getModel();
301                while (index >= min) {
302                    String[] names = getTypeAndNames(name.get(index));
303                    model.remove(index);
304                    Conditional c = InstanceManager.getDefault(ConditionalManager.class).getBySystemName(names[2]);
305                    if (c != null) {
306                        Logix x = InstanceManager.getDefault(ConditionalManager.class).getParentLogix(names[2]);
307                        if (x != null) {
308                            x.deActivateLogix();
309                            x.deleteConditional(names[2]);
310                            x.activateLogix();
311                        }
312                        InstanceManager.getDefault(ConditionalManager.class).deregister(c);
313                        name.remove(index);
314                        index--;
315                    }
316                }
317                index++;
318                if (index >= model.getSize()) {
319                    index = model.getSize() - 1;
320                }
321                if (index >= 0) {
322                    list.setSelectedIndex(index);
323                }
324            }
325        }
326        JScrollPane scrollPane = new JScrollPane(list);
327        button.addActionListener(new EmptyListener(list, names));
328        button.setMaximumSize(button.getPreferredSize());
329        makeDialog(scrollPane, button, parent, rbm.getString("EmptyConditionalTitle"));
330    }
331
332    /**
333     * Find type of element and its names from a name that may be a user name or
334     * a system name.
335     * <p>
336     * Searches each Manager for a reference to the "name".
337     *
338     * @param name string (name base) to look for
339     * @return 4 element String array: {Type, userName, sysName, numListeners}  - 
340     * This should probably return an instance of a custom type rather than a bunch of string names
341     */
342    @Nonnull
343    static String[] getTypeAndNames(@Nonnull String name) {
344        log.debug("getTypeAndNames for \"{}\"", name);
345
346        String[] result;
347
348        result = checkForOneTypeAndNames(InstanceManager.getDefault(SensorManager.class), "Sensor", name);
349        if (result != null) return result;
350
351        result = checkForOneTypeAndNames(InstanceManager.getDefault(TurnoutManager.class), "Turnout", name);
352        if (result != null) return result;
353
354        result = checkForOneTypeAndNames(InstanceManager.getDefault(LightManager.class), "Light", name);
355        if (result != null) return result;
356
357        result = checkForOneTypeAndNames(InstanceManager.getDefault(SignalHeadManager.class), "SignalHead", name);
358        if (result != null) return result;
359
360        result = checkForOneTypeAndNames(InstanceManager.getDefault(ConditionalManager.class), "Conditional", name);
361        if (result != null) return result;
362
363        result = checkForOneTypeAndNames(InstanceManager.getDefault(BlockManager.class), "Block", name);
364        if (result != null) return result;
365
366        result = checkForOneTypeAndNames(InstanceManager.getDefault(SectionManager.class), "Section", name);  // old code has "Block" for type
367        if (result != null) return result;
368
369        result = checkForOneTypeAndNames(InstanceManager.getDefault(OBlockManager.class), "OBlock", name);
370        if (result != null) return result;
371
372
373        return new String[]{"", name, name, "0"};
374
375    }
376    // captive for above
377    @edu.umd.cs.findbugs.annotations.SuppressFBWarnings(value = "PZLA_PREFER_ZERO_LENGTH_ARRAYS",
378        justification = "null return for normal (no error) case is easy to check, and this is a really wierd array")
379    // This should probably return an instance of a custom type rather than a bunch of string names
380    static private String[] checkForOneTypeAndNames( @Nonnull Manager<? extends NamedBean> manager, @Nonnull String type, @Nonnull String beanName) {
381        NamedBean bean = manager.getBySystemName(beanName);
382        if (bean != null) return new String[]{type, bean.getUserName(), bean.getSystemName(), Integer.toString(bean.getNumPropertyChangeListeners())};
383
384        bean = manager.getByUserName(beanName);
385        if (bean != null) return new String[]{type, bean.getUserName(), bean.getSystemName(), Integer.toString(bean.getNumPropertyChangeListeners())};
386
387        return null;
388    }
389
390    /**
391     * Check if a given string is either a user or a system name.
392     *
393     * @param name the string to compare
394     * @param found whether the item has already been found somewhere
395     * @param names array containing system and user name as items 0 and 1
396     * @param line1 message line 1 to use if string is not matched
397     * @param line2 message line 2 to use if string is not matched
398     * @param line message line to use if string is matched
399     * @param tempText body of text to add to, a global variable
400     * @return false if name is null or cannot be matched to the names array
401     */
402    static boolean testName(String name, boolean found, String[] names, String line1, String line2,
403            String line, StringBuilder tempText) {
404        if (name == null) {
405            return false;
406        }
407        String sysName = names[2];
408        String userName = names[1];
409        if (name.equals(sysName) || name.equals(userName)) {
410            if (!found) {
411                if (line1 != null) {
412                    tempText.append(line1);
413                }
414                if (line2 != null) {
415                    tempText.append(line2);
416                }
417            }
418            tempText.append(line);
419            return true;
420        }
421        return false;
422    }
423
424    /**
425     * Search if a given string is used as the name of a NamedBean.
426     *
427     * @param name the string to look for
428     * @param text body of the message to be displayed reporting the result
429     * @return true if name is found at least once as a bean name
430     */
431    static boolean search(String name, JTextArea text) {
432        String[] names = getTypeAndNames(name);
433        if (log.isDebugEnabled()) {
434            log.debug("search for {} as {} \"{}\" ({})", name, names[0], names[1], names[2]);
435        }
436        if (names[0].length() == 0) {
437            if (text != null) {
438                text.append(MessageFormat.format(rbm.getString("ElementNotFound"), (Object[]) names));
439                return false;
440            }
441        }
442        if (text != null) {
443            text.append(MessageFormat.format(rbm.getString("ReferenceFollows"), (Object[]) names));
444        }
445        String sysName = names[2];
446        String userName = names[1];
447        int referenceCount = 0;
448        StringBuilder tempText;
449        boolean found = false;
450        boolean empty = true;
451        // search for references among each class known to be listeners
452        Iterator<String> iter1 = getSystemNameList(InstanceManager.getDefault(LogixManager.class)).iterator();
453        while (iter1.hasNext()) {
454            // get the next Logix
455            String sName = iter1.next();
456            Logix x = InstanceManager.getDefault(LogixManager.class).getBySystemName(sName);
457            if (x == null) {
458                log.error("Error getting Logix  - {}", sName);
459                break;
460            }
461            tempText = new StringBuilder();
462            String uName = x.getUserName();
463            String line1 = MessageFormat.format(rbm.getString("ReferenceTitle"),
464                    new Object[]{"", Bundle.getMessage("BeanNameLogix"), uName, sName});
465            for (int i = 0; i < x.getNumConditionals(); i++) {
466                sName = x.getConditionalByNumberOrder(i);
467                if (sName == null) {
468                    log.error("Null conditional system name");
469                    break;
470                }
471                Conditional c = InstanceManager.getDefault(ConditionalManager.class).getBySystemName(sName);
472                if (c == null) {
473                    log.error("Invalid conditional system name - {}", sName);
474                    break;
475                }
476                uName = c.getUserName();
477                String line2 = MessageFormat.format(rbm.getString("ReferenceTitle"),
478                        new Object[]{"\t", Bundle.getMessage("BeanNameConditional"), uName, sName});
479                String line = MessageFormat.format(rbm.getString("ConditionalReference"), "\t");
480                if (sysName.equals(sName) || (userName != null && userName.length() > 0 && userName.equals(uName))) {
481                    if (testName(sysName, found, names, line1, null, line, tempText)) {
482                        found = true;
483                        referenceCount++;
484                    }
485                }
486                List<ConditionalVariable> variableList = c.getCopyOfStateVariables();
487                for (int k = 0; k < variableList.size(); k++) {
488                    ConditionalVariable v = variableList.get(k);
489                    line = MessageFormat.format(rbm.getString("VariableReference"),
490                            new Object[]{"\t\t", v.getTestTypeString(), v.getDataString()});
491                    if (testName(v.getName(), found, names, line1, line2, line, tempText)) {
492                        found = true;
493                        referenceCount++;
494                    }
495                }
496                List<ConditionalAction> actionList = c.getCopyOfActions();
497                for (int k = 0; k < actionList.size(); k++) {
498                    ConditionalAction a = actionList.get(k);
499                    line = MessageFormat.format(rbm.getString("ActionReference"),
500                            new Object[]{"\t\t", a.getTypeString(), a.getOptionString(false), a.getActionDataString()});
501                    if (testName(a.getDeviceName(), found, names, line1, line2, line, tempText)) {
502                        found = true;
503                        referenceCount++;
504                    }
505                }
506                if (text != null && found) {
507                    text.append(tempText.toString());
508                    tempText = new StringBuilder();
509                    found = false;
510                    empty = false;
511                    line1 = null;
512                }
513            }
514            if (text != null && found) {
515                text.append(tempText.toString());
516                found = false;
517                empty = false;
518            }
519        }
520        if (text != null) {
521            if (empty) {
522                text.append("\t" + MessageFormat.format(rbm.getString("NoReference"), "Logix"));
523                // cannot put escaped tab char at start of getString
524            } else {
525                text.append("\n");
526            }
527        }
528
529        tempText = new StringBuilder();
530        found = false;
531        empty = true;
532        OBlockManager oBlockManager = InstanceManager.getDefault(OBlockManager.class);
533        iter1 = getSystemNameList(oBlockManager).iterator();
534        while (iter1.hasNext()) {
535            // get the next Logix
536            String sName = iter1.next();
537            OBlock block = oBlockManager.getBySystemName(sName);
538            if (block==null){
539                continue;
540            }
541            String uName = block.getUserName();
542            String line1 = MessageFormat.format(rbm.getString("ReferenceTitle"),
543                    new Object[]{" ", Bundle.getMessage("BeanNameOBlock"), uName, sName});
544            Sensor sensor = block.getSensor();
545            if (sensor != null) {
546                String line = MessageFormat.format(rbm.getString("OBlockSensor"), "\t");
547                if (testName(sensor.getSystemName(), found, names, line1, null, line, tempText)) {
548                    found = true;
549                    referenceCount++;
550                }
551            }
552            if (text != null && found) {
553                text.append(tempText.toString());
554                tempText = new StringBuilder();
555                found = false;
556                empty = false;
557            }
558        }
559        if (text != null) {
560            if (empty) {
561                text.append(MessageFormat.format(rbm.getString("NoReference"), "OBlock"));
562            } else {
563                text.append("\n");
564            }
565        }
566
567        tempText = new StringBuilder();
568        found = false;
569        empty = true;
570        RouteManager routeManager = InstanceManager.getDefault(RouteManager.class);
571        iter1 = getSystemNameList(routeManager).iterator();
572        while (iter1.hasNext()) {
573            // get the next Logix
574            String sName = iter1.next();
575            Route r = routeManager.getBySystemName(sName);
576            if (r == null) {
577                log.error("Error getting Route  - {}", sName);
578                break;
579            }
580            String uName = r.getUserName();
581            String line1 = MessageFormat.format(rbm.getString("ReferenceTitle"),
582                    new Object[]{" ", Bundle.getMessage("BeanNameRoute"), uName, sName});
583            for (int i = 0; i < Route.MAX_CONTROL_SENSORS; i++) {
584                String line = "\t" + MessageFormat.format(rbm.getString("ControlReference"), Bundle.getMessage("BeanNameSensor"));
585                if (testName(r.getRouteSensorName(i), found, names, line1, null, line, tempText)) {
586                    found = true;
587                    referenceCount++;
588                }
589            }
590            String line = MessageFormat.format("TurnoutsAlignedSensor", Bundle.getMessage("BeanNameSensor"));
591            if (testName(r.getTurnoutsAlignedSensor(), found, names, line1, null, line, tempText)) {
592                found = true;
593                referenceCount++;
594            }
595            line = "\t" + MessageFormat.format(rbm.getString("ControlReference"), Bundle.getMessage("BeanNameTurnout"));
596            if (testName(r.getControlTurnout(), found, names, line1, null, line, tempText)) {
597                found = true;
598                referenceCount++;
599            }
600            line = MessageFormat.format("LockControlTurnout", Bundle.getMessage("BeanNameTurnout"));
601            if (testName(r.getLockControlTurnout(), found, names, line1, null, line, tempText)) {
602                found = true;
603                referenceCount++;
604            }
605            for (int i = 0; i < r.getNumOutputTurnouts(); i++) {
606                line = "\t" + MessageFormat.format(rbm.getString("OutputReference"), Bundle.getMessage("BeanNameTurnout"));
607                if (testName(r.getOutputTurnoutByIndex(i), found, names, line1, null, line, tempText)) {
608                    found = true;
609                    referenceCount++;
610                }
611            }
612            for (int i = 0; i < r.getNumOutputSensors(); i++) {
613                line = "\t" +  MessageFormat.format(rbm.getString("OutputReference"), Bundle.getMessage("BeanNameSensor"));
614                if (testName(r.getOutputSensorByIndex(i), found, names, line1, null, line, tempText)) {
615                    found = true;
616                    referenceCount++;
617                }
618            }
619            if (text != null && found) {
620                text.append(tempText.toString());
621                tempText = new StringBuilder();
622                found = false;
623                empty = false;
624            }
625        }
626        if (text != null) {
627            if (empty) {
628                text.append(MessageFormat.format(rbm.getString("NoReference"), "Route"));
629            } else {
630                text.append("\n");
631            }
632        }
633
634        tempText = new StringBuilder();
635        found = false;
636        empty = true;
637        TransitManager transitManager = InstanceManager.getDefault(TransitManager.class);
638        iter1 = getSystemNameList(transitManager).iterator();
639        while (iter1.hasNext()) {
640            // get the next Logix
641            String sName = iter1.next();
642            Transit transit = transitManager.getBySystemName(sName);
643            if (transit == null) {
644                log.error("Error getting Transit - {}", sName);
645                break;
646            }
647            String uName = transit.getUserName();
648            String line1 = MessageFormat.format(rbm.getString("ReferenceTitle"),
649                    new Object[]{" ", Bundle.getMessage("BeanNameTransit"), uName, sName});
650            List<TransitSection> sectionList = transit.getTransitSectionList();
651            for (int i = 0; i < sectionList.size(); i++) {
652                TransitSection transitSection = sectionList.get(i);
653                Section section = transitSection.getSection();
654                uName = section.getUserName();
655                sName = section.getSystemName();
656                String line2 = MessageFormat.format(rbm.getString("ReferenceTitle"),
657                        new Object[]{"\t", rbm.getString("TransitSection"), uName, sName});
658                if (sName.equals(sysName) || uName.equals(userName)) {
659                    tempText.append(line1);
660                    tempText.append(line2);
661                    tempText.append(MessageFormat.format(rbm.getString("SectionReference"), "\t\t"));
662                    found = true;
663                    referenceCount++;
664                }
665                String line = MessageFormat.format(rbm.getString("ForwardBlocking"), "\t\t");
666                if (testName(section.getForwardBlockingSensorName(), found, names, line1, line2, line, tempText)) {
667                    found = true;
668                    referenceCount++;
669                }
670                line = MessageFormat.format(rbm.getString("ForwardStopping"), "\t\t");
671                if (testName(section.getForwardStoppingSensorName(), found, names, line1, line2, line, tempText)) {
672                    found = true;
673                    referenceCount++;
674                }
675                line = MessageFormat.format(rbm.getString("ReverseBlocking"), "\t\t");
676                if (testName(section.getReverseBlockingSensorName(), found, names, line1, line2, line, tempText)) {
677                    found = true;
678                    referenceCount++;
679                }
680                line = MessageFormat.format(rbm.getString("ReverseStopping"), "\t\t");
681                if (testName(section.getReverseStoppingSensorName(), found, names, line1, line2, line, tempText)) {
682                    found = true;
683                    referenceCount++;
684                }
685                List<Block> blockList = section.getBlockList();
686
687                for (int k = 0; k < blockList.size(); k++) {
688                    Block block = blockList.get(k);
689                    sName = block.getSystemName();
690                    uName = block.getUserName();
691                    tempText.append(MessageFormat.format(rbm.getString("ReferenceTitle"),
692                            new Object[]{"\t\t", Bundle.getMessage("BeanNameBlock"), uName, sName}));
693                    if (sName.equals(sysName) || uName.equals(userName)) {
694                        tempText.append(MessageFormat.format(rbm.getString("BlockReference"), "\t\t"));
695                        found = true;
696                        referenceCount++;
697                    }
698                    Sensor sensor = block.getSensor();
699                    if (sensor != null) {
700                        line = MessageFormat.format(rbm.getString("BlockSensor"), "\t\t");
701                        if (testName(sensor.getSystemName(), found, names, line1, line2, line, tempText)) {
702                            found = true;
703                            referenceCount++;
704                        }
705                    }
706                }
707                if (text != null && found) {
708                    text.append(tempText.toString());
709                    tempText = new StringBuilder();
710                    found = false;
711                    empty = false;
712                    line1 = null;
713                }
714            }
715            if (text != null && found) {
716                text.append(tempText.toString());
717                tempText = new StringBuilder();
718                found = false;
719                empty = false;
720            }
721        }
722        if (text != null) {
723            if (empty) {
724                text.append(MessageFormat.format(rbm.getString("NoReference"), "Transit"));
725            } else {
726                text.append("\n");
727            }
728        }
729
730        // if (text != null) {
731        //   text.append(rbm.getString("NestMessage"));
732        // }
733        tempText = new StringBuilder();
734        found = false;
735        empty = true;
736        SectionManager sectionManager = InstanceManager.getDefault(SectionManager.class);
737        List<String> sysNameList = new ArrayList<>(getSystemNameList(sectionManager));
738
739        transitManager = InstanceManager.getDefault(TransitManager.class);
740        iter1 = getSystemNameList(transitManager).iterator();
741        while (iter1.hasNext()) {
742            // get the next Logix
743            String sName = iter1.next();
744            Transit transit = transitManager.getBySystemName(sName);
745            if (transit != null) {
746                List<TransitSection> sectionList = transit.getTransitSectionList();
747                for (int i = 0; i < sectionList.size(); i++) {
748                    TransitSection transitSection = sectionList.get(i);
749                    Section section = transitSection.getSection();
750                    sysNameList.remove(section.getSystemName());
751                }
752            }
753        }
754        iter1 = sysNameList.iterator();
755        while (iter1.hasNext()) {
756            // get the next Logix
757            String sName = iter1.next();
758            Section section = sectionManager.getBySystemName(sName);
759            if (section == null) {
760                log.error("Error getting Section - {}", sName);
761                break;
762            }
763            String uName = section.getUserName();
764            String line1 = MessageFormat.format(rbm.getString("ReferenceTitle"),
765                    new Object[]{" ", Bundle.getMessage("BeanNameSection"), uName, sName});
766            if (sName.equals(sysName) || uName.equals(userName)) {
767                tempText.append(MessageFormat.format(rbm.getString("SectionReference"), "\t"));
768
769                found = true;
770                referenceCount++;
771            }
772            String line = MessageFormat.format(rbm.getString("ForwardBlocking"), "\t");
773            if (testName(section.getForwardBlockingSensorName(), found, names, line1, null, line, tempText)) {
774                found = true;
775                referenceCount++;
776            }
777            line = MessageFormat.format(rbm.getString("ForwardStopping"), "\t");
778            if (testName(section.getForwardStoppingSensorName(), found, names, line1, null, line, tempText)) {
779                found = true;
780                referenceCount++;
781            }
782            line = MessageFormat.format(rbm.getString("ReverseBlocking"), "\t");
783            if (testName(section.getReverseBlockingSensorName(), found, names, line1, null, line, tempText)) {
784                found = true;
785                referenceCount++;
786            }
787            line = MessageFormat.format(rbm.getString("ReverseStopping"), "\t");
788            if (testName(section.getReverseStoppingSensorName(), found, names, line1, null, line, tempText)) {
789                found = true;
790                referenceCount++;
791            }
792
793            List<Block> blockList = section.getBlockList();
794            for (int k = 0; k < blockList.size(); k++) {
795                Block block = blockList.get(k);
796                sName = block.getSystemName();
797                uName = block.getUserName();
798                String line2 = MessageFormat.format(rbm.getString("ReferenceTitle"),
799                        new Object[]{"\t", Bundle.getMessage("BeanNameBlock"), uName, sName});
800                if (sName.equals(sysName) || (uName != null && uName.equals(userName))) {
801                    tempText.append(line2);
802                    tempText.append(MessageFormat.format(rbm.getString("BlockReference"), "\t"));
803                    found = true;
804                    referenceCount++;
805                }
806                Sensor sensor = block.getSensor();
807                if (sensor != null) {
808                    line = MessageFormat.format(rbm.getString("BlockSensor"), "\t\t");
809                    if (testName(sensor.getSystemName(), found, names, line1, line2, line, tempText)) {
810                        found = true;
811                        referenceCount++;
812                    }
813                }
814            }
815            if (text != null && found) {
816                text.append(tempText.toString());
817                tempText = new StringBuilder();
818                found = false;
819                empty = false;
820            }
821        }
822        if (text != null) {
823            if (empty) {
824                text.append(MessageFormat.format(rbm.getString("NoReference"), "Section"));
825            } else {
826                text.append("\n");
827            }
828        }
829
830        tempText = new StringBuilder();
831        found = false;
832        empty = true;
833        BlockManager blockManager = InstanceManager.getDefault(BlockManager.class);
834        sysNameList = new ArrayList<>(getSystemNameList(blockManager));
835
836        sectionManager = InstanceManager.getDefault(SectionManager.class);
837        iter1 = getSystemNameList(sectionManager).iterator();
838        while (iter1.hasNext()) {
839            String sName = iter1.next();
840            Section section = sectionManager.getBySystemName(sName);
841            if (section != null) {
842                for (Block block : section.getBlockList()) {
843                    sysNameList.remove(block.getSystemName());
844                }
845            }
846        }
847        iter1 = sysNameList.iterator();
848        while (iter1.hasNext()) {
849            // get the next Logix
850            String sName = iter1.next();
851            Block b = blockManager.getBySystemName(sName);
852            if (b == null) {
853                continue;
854            }
855            String uName = b.getUserName();
856            String line1 = MessageFormat.format(rbm.getString("ReferenceTitle"),
857                    new Object[]{" ", Bundle.getMessage("BeanNameBlock"), uName, sName});
858            if (sName.equals(sysName) || (uName != null && uName.equals(userName))) {
859                tempText.append(line1);
860                tempText.append(MessageFormat.format(rbm.getString("BlockReference"), "\t"));
861                found = true;
862                referenceCount++;
863            }
864            Sensor s = b.getSensor();
865            if (s != null) {
866                String line = MessageFormat.format(rbm.getString("BlockSensor"), "\t\t");
867                if (testName(s.getSystemName(), found, names, line1, null, line, tempText)) {
868                    found = true;
869                    referenceCount++;
870                }
871            }
872            if (text != null && found) {
873                text.append(tempText.toString());
874                tempText = new StringBuilder();
875                found = false;
876                empty = false;
877            }
878        }
879        if (text != null) {
880            if (empty) {
881                text.append(MessageFormat.format(rbm.getString("NoReference"), "Block"));
882            } else {
883                text.append("\n");
884            }
885        }
886
887        tempText = new StringBuilder();
888        found = false;
889        empty = true;
890        LayoutBlockManager lbm = InstanceManager.getDefault(LayoutBlockManager.class);
891        iter1 = getSystemNameList(lbm).iterator();
892        while (iter1.hasNext()) {
893            // get the next Logix
894            String sName = iter1.next();
895            LayoutBlock lb = lbm.getBySystemName(sName);
896            if (lb == null) {
897                log.error("Error getting LayoutBlock - {}", sName);
898                break;
899            }
900            String uName = lb.getUserName();
901            String line1 = MessageFormat.format(rbm.getString("ReferenceTitle"),
902                    new Object[]{" ", rbm.getString("LayoutBlock"), uName, sName});
903            Sensor s = lb.getOccupancySensor();
904            if (s != null) {
905                String line = MessageFormat.format(rbm.getString("OccupancySensor"), "\t\t");
906                if (testName(s.getSystemName(), found, names, line1, null, line, tempText)) {
907                    found = true;
908                    referenceCount++;
909                }
910            }
911            if (text != null && found) {
912                text.append(tempText.toString());
913                tempText = new StringBuilder();
914                found = false;
915                empty = false;
916            }
917        }
918        if (text != null) {
919            if (empty) {
920                text.append(MessageFormat.format(rbm.getString("NoReference"), "LayoutBlock"));
921            } else {
922                text.append("\n");
923            }
924        }
925
926        tempText = new StringBuilder();
927        found = false;
928        empty = true;
929        Enumeration<BlockBossLogic> enumeration = Collections.enumeration(
930            InstanceManager.getDefault(BlockBossLogicProvider.class).provideAll());
931        while (enumeration.hasMoreElements()) {
932            // get the next Logix
933            BlockBossLogic bbl = enumeration.nextElement();
934            String sName = bbl.getName();
935            String uName = bbl.getDrivenSignal();
936            String line1 = MessageFormat.format(rbm.getString("ReferenceTitle"),
937                    new Object[]{" ", rbm.getString("BlockBossLogic"), uName, sName});
938            if (uName.equals(sysName) || uName.equals(userName) || sName.equals(sysName) || sName.equals(userName)) {
939                tempText.append(line1);
940                tempText.append(MessageFormat.format(rbm.getString("SignalReference"), "\t"));
941                found = true;
942                referenceCount++;
943            }
944            String line = MessageFormat.format(rbm.getString("WatchSensorReference"), "1\t");
945            if (testName(bbl.getSensor1(), found, names, line1, null, line, tempText)) {
946                found = true;
947                referenceCount++;
948            }
949            line = MessageFormat.format(rbm.getString("WatchSensorReference"), "2\t");
950            if (testName(bbl.getSensor2(), found, names, line1, null, line, tempText)) {
951                found = true;
952                referenceCount++;
953            }
954            line = MessageFormat.format(rbm.getString("WatchSensorReference"), "3\t");
955            if (testName(bbl.getSensor3(), found, names, line1, null, line, tempText)) {
956                found = true;
957                referenceCount++;
958            }
959            line = MessageFormat.format(rbm.getString("WatchSensorReference"), "4\t");
960            if (testName(bbl.getSensor4(), found, names, line1, null, line, tempText)) {
961                found = true;
962                referenceCount++;
963            }
964            line = MessageFormat.format(rbm.getString("WatchSensorReference"), "5\t");
965            if (testName(bbl.getSensor5(), found, names, line1, null, line, tempText)) {
966                found = true;
967                referenceCount++;
968            }
969            line = MessageFormat.format(rbm.getString("WatchTurnoutReference"), "\t");
970            if (testName(bbl.getTurnout(), found, names, line1, null, line, tempText)) {
971                found = true;
972                referenceCount++;
973            }
974            line = MessageFormat.format(rbm.getString("WatchSignalReference"), "1\t");
975            if (testName(bbl.getWatchedSignal1(), found, names, line1, null, line, tempText)) {
976                found = true;
977                referenceCount++;
978            }
979            line = MessageFormat.format(rbm.getString("WatchTurnoutReference"), "1Alt\t");
980            if (testName(bbl.getWatchedSignal1Alt(), found, names, line1, null, line, tempText)) {
981                found = true;
982                referenceCount++;
983            }
984            line = MessageFormat.format(rbm.getString("WatchTurnoutReference"), "2\t");
985            if (testName(bbl.getWatchedSignal2(), found, names, line1, null, line, tempText)) {
986                found = true;
987                referenceCount++;
988            }
989            line = MessageFormat.format(rbm.getString("WatchTurnoutReference"), "2Alt\t");
990            if (testName(bbl.getWatchedSignal2Alt(), found, names, line1, null, line, tempText)) {
991                found = true;
992                referenceCount++;
993            }
994            line = MessageFormat.format(rbm.getString("WatchSensorReference"), "1\t");
995            if (testName(bbl.getWatchedSensor1(), found, names, line1, null, line, tempText)) {
996                found = true;
997                referenceCount++;
998            }
999            line = MessageFormat.format(rbm.getString("WatchSensorReference"), "1Alt\t");
1000            if (testName(bbl.getWatchedSensor1Alt(), found, names, line1, null, line, tempText)) {
1001                found = true;
1002                referenceCount++;
1003            }
1004            line = MessageFormat.format(rbm.getString("WatchSensorReference"), "2\t");
1005            if (testName(bbl.getWatchedSensor2(), found, names, line1, null, line, tempText)) {
1006                found = true;
1007                referenceCount++;
1008            }
1009            line = MessageFormat.format(rbm.getString("WatchSensorReference"), "2Alt\t");
1010            if (testName(bbl.getWatchedSensor2Alt(), found, names, line1, null, line, tempText)) {
1011                found = true;
1012                referenceCount++;
1013            }
1014            if (text != null && found) {
1015                text.append(tempText.toString());
1016                tempText = new StringBuilder();
1017                found = false;
1018                empty = false;
1019            }
1020        }
1021        if (text != null) {
1022            if (empty) {
1023                text.append(MessageFormat.format(rbm.getString("NoReference"), "BlockBossLogic"));
1024            } else {
1025                text.append("\n");
1026            }
1027        }
1028
1029        tempText = new StringBuilder();
1030        found = false;
1031        empty = true;
1032        ConditionalManager conditionalManager = InstanceManager.getDefault(ConditionalManager.class);
1033        sysNameList = new ArrayList<>(getSystemNameList(conditionalManager));
1034
1035        iter1 = getSystemNameList(InstanceManager.getDefault(LogixManager.class)).iterator();
1036        while (iter1.hasNext()) {
1037            String sName = iter1.next();
1038            Logix x = InstanceManager.getDefault(LogixManager.class).getBySystemName(sName);
1039            if (x == null){
1040                continue;
1041            }
1042            for (int i = 0; i < x.getNumConditionals(); i++) {
1043                sName = x.getConditionalByNumberOrder(i);
1044                sysNameList.remove(sName);
1045            }
1046        }
1047        iter1 = sysNameList.iterator();
1048        while (iter1.hasNext()) {
1049            // get the next Logix
1050            String sName = iter1.next();
1051            Conditional c = conditionalManager.getBySystemName(sName);
1052            if (c == null) {
1053                log.error("Error getting Condition - {}", sName);
1054                break;
1055            }
1056            String uName = c.getUserName();
1057            String line1 = MessageFormat.format(rbm.getString("ReferenceTitle"),
1058                    new Object[]{" ", Bundle.getMessage("BeanNameConditional"), uName, sName});
1059            if (sName.equals(sysName) || uName.equals(userName)) {
1060                tempText.append(line1);
1061                tempText.append(MessageFormat.format(rbm.getString("ConditionalReference"), "\t"));
1062                found = true;
1063                //referenceCount++; Don't count, this conditional is orphaned by logix(es)
1064            }
1065            List<ConditionalVariable> variableList = c.getCopyOfStateVariables();
1066            for (int k = 0; k < variableList.size(); k++) {
1067                ConditionalVariable v = variableList.get(k);
1068                String line = MessageFormat.format(rbm.getString("VariableReference"),
1069                        new Object[]{"\t\t", v.getTestTypeString(), v.getDataString()});
1070                if (testName(v.getName(), found, names, line1, null, line, tempText)) {
1071                    found = true;
1072                    //referenceCount++; Don't count, this conditional is orphaned by logix(es)
1073                }
1074            }
1075            List<ConditionalAction> actionList = c.getCopyOfActions();
1076            for (int k = 0; k < actionList.size(); k++) {
1077                ConditionalAction a = actionList.get(k);
1078                String line = MessageFormat.format(rbm.getString("ActionReference"),
1079                        new Object[]{"\t\t", a.getTypeString(), a.getOptionString(false), a.getActionDataString()});
1080                if (testName(a.getDeviceName(), found, names, line1, null, line, tempText)) {
1081                    found = true;
1082                    //referenceCount++; Don't count, this conditional is orphaned by logix(es)
1083                }
1084            }
1085            if (text != null && found) {
1086                text.append(tempText.toString());
1087                tempText = new StringBuilder();
1088                found = false;
1089                empty = false;
1090                line1 = null;
1091            }
1092        }
1093        if (text != null) {
1094            if (empty) {
1095                text.append(MessageFormat.format(rbm.getString("NoReference"), "Conditional"));
1096            }
1097            text.append("\n");
1098        }
1099
1100        found = false;
1101        empty = true;
1102        Set<Editor> panelList = InstanceManager.getDefault(EditorManager.class).getAll();
1103        for (Editor panelEditor : panelList) {
1104            name = panelEditor.getTitle();
1105            String line1 = MessageFormat.format(rbm.getString("ReferenceTitle"),
1106                    new Object[]{" ", rbm.getString("Panel"), name, name});
1107            List<Positionable> contents = panelEditor.getContents();
1108            for (int k = 0; k < contents.size(); k++) {
1109                Positionable o = contents.get(k);
1110                if (o.getClass().getName().equals("jmri.jmrit.display.SensorIcon")) {
1111                    name = ((SensorIcon) o).getSensor().getSystemName();
1112                    String line = MessageFormat.format(rbm.getString("PanelReference"),
1113                            new Object[]{"\t", Bundle.getMessage("BeanNameSensor")});
1114                    if (testName(name, found, names, line1, null, line, tempText)) {
1115                        found = true;
1116                        referenceCount++;
1117                    }
1118                } else if (o.getClass().getName().equals("jmri.jmrit.display.TurnoutIcon")) {
1119                    name = ((TurnoutIcon) o).getTurnout().getSystemName();
1120                    String line = MessageFormat.format(rbm.getString("PanelReference"),
1121                            new Object[]{"\t", Bundle.getMessage("BeanNameTurnout")});
1122                    if (testName(name, found, names, line1, null, line, tempText)) {
1123                        found = true;
1124                        referenceCount++;
1125                    }
1126                } else if (o.getClass().getName().equals("jmri.jmrit.display.SignalHeadIcon")) {
1127                    name = ((SignalHeadIcon) o).getSignalHead().getSystemName();
1128                    String line = MessageFormat.format(rbm.getString("PanelReference"),
1129                            new Object[]{"\t", Bundle.getMessage("BeanNameSignalHead")});
1130                    if (testName(name, found, names, line1, null, line, tempText)) {
1131                        found = true;
1132                        referenceCount++;
1133                    }
1134                } else if (o.getClass().getName().equals("jmri.jmrit.display.MultiSensorIcon")) {
1135                    MultiSensorIcon msi = (MultiSensorIcon) o;
1136                    for (int j = 0; j < msi.getNumEntries(); j++) {
1137                        name = msi.getSensorName(j);
1138                        String line = MessageFormat.format(rbm.getString("PanelReference"),
1139                                new Object[]{"\t", Bundle.getMessage("MultiSensor")});
1140                        if (testName(name, found, names, line1, null, line, tempText)) {
1141                            found = true;
1142                            referenceCount++;
1143                        }
1144                    }
1145                } else if (o.getClass().getName().equals("jmri.jmrit.display.IndicatorTurnoutIcon")) {
1146                    IndicatorTurnoutIcon ito = (IndicatorTurnoutIcon) o;
1147                    name = ito.getTurnout().getSystemName();
1148                    String line = MessageFormat.format(rbm.getString("PanelReference"),
1149                            new Object[]{"\t", Bundle.getMessage("IndicatorTO")});
1150                    if (testName(name, found, names, line1, null, line, tempText)) {
1151                        found = true;
1152                        referenceCount++;
1153                    }
1154                    Sensor sensor = ito.getOccSensor();
1155                    if (sensor != null) {
1156                        name = sensor.getSystemName();
1157                        line = MessageFormat.format(rbm.getString("PanelReference"),
1158                                new Object[]{"\t", Bundle.getMessage("IndicatorTO")});
1159                        if (testName(name, found, names, line1, null, line, tempText)) {
1160                            found = true;
1161                            referenceCount++;
1162                        }
1163                    }
1164                    OBlock block = ito.getOccBlock();
1165                    if (block != null) {
1166                        sensor = block.getSensor();
1167                        if (sensor != null) {
1168                            name = sensor.getSystemName();
1169                            line = MessageFormat.format(rbm.getString("PanelReference"),
1170                                    new Object[]{"\t", Bundle.getMessage("IndicatorTO")});
1171                            if (testName(name, found, names, line1, null, line, tempText)) {
1172                                found = true;
1173                                referenceCount++;
1174                            }
1175                        }
1176                    }
1177                } else if (o.getClass().getName().equals("jmri.jmrit.display.IndicatorTrackIcon")) {
1178                    IndicatorTrackIcon track = (IndicatorTrackIcon) o;
1179                    Sensor sensor = track.getOccSensor();
1180                    if (sensor != null) {
1181                        name = sensor.getSystemName();
1182                        String line = MessageFormat.format(rbm.getString("PanelReference"),
1183                                new Object[]{"\t", Bundle.getMessage("IndicatorTrack")});
1184                        if (testName(name, found, names, line1, null, line, tempText)) {
1185                            found = true;
1186                            referenceCount++;
1187                        }
1188                    }
1189                    OBlock block = track.getOccBlock();
1190                    if (block != null) {
1191                        sensor = block.getSensor();
1192                        if (sensor != null) {
1193                            name = sensor.getSystemName();
1194                            String line = MessageFormat.format(rbm.getString("PanelReference"),
1195                                    new Object[]{"\t", Bundle.getMessage("IndicatorTrack")});
1196                            if (testName(name, found, names, line1, null, line, tempText)) {
1197                                found = true;
1198                                referenceCount++;
1199                            }
1200                        }
1201                    }
1202                }
1203                if (text != null && found) {
1204                    text.append(tempText.toString());
1205                    tempText = new StringBuilder();
1206                    found = false;
1207                    empty = false;
1208                    line1 = null;
1209                }
1210            }
1211            if (text != null) {
1212                if (empty) {
1213                    text.append(MessageFormat.format(rbm.getString("NoReference"), "Panel"));
1214                }
1215            }
1216        }
1217
1218        if (text != null) {
1219            if (referenceCount == 0) {
1220                text.append(MessageFormat.format(rbm.getString("Orphan"), (Object[]) names));
1221            } else {
1222                text.append(MessageFormat.format(rbm.getString("ReferenceFound"),
1223                        new Object[]{referenceCount, userName, sysName}));
1224            }
1225        }
1226        if (names[0] != null) {
1227            // The manager is always a listener
1228            int numListeners = Integer.parseInt(names[3]) - 1;
1229            // PickLists are also listeners
1230            numListeners = numListeners - PickListModel.getNumInstances(names[0]);
1231            if (names[0].equals("Sensor")) {
1232                numListeners = numListeners - PickListModel.getNumInstances("MultiSensor"); // NOI18N
1233            }
1234
1235            if (numListeners > referenceCount) {
1236                if (names[0].length() == 0) {
1237                    names[0] = "Unknown Type?";
1238                }
1239                /*
1240                 JOptionPane.showMessageDialog(null,
1241                 MessageFormat.format(rbm.getString("OrphanName"), (Object[])names)+" has "+numListeners+
1242                 " listeners installed and only "+referenceCount+
1243                 " references found.\n"+names[0]+
1244                 " Tables are listeneners.  Check that the table is closed.",
1245                 rbm.getString("infoTitle"), JOptionPane.INFORMATION_MESSAGE);
1246                 */
1247                if (text != null) {
1248                    text.append(MessageFormat.format(rbm.getString("OrphanName"), (Object[]) names) + " has " + numListeners
1249                            + " listeners installed and only " + referenceCount
1250                            + " references found.\n" + names[0]
1251                            + " Tables are listeneners.  Check that the table is closed.");
1252                }
1253            }
1254        }
1255        return (referenceCount > 0);
1256    }
1257
1258    /**
1259     * Build and display a dialog box with an OK button and optional 2nd button.
1260     *
1261     * @param component Body of message to put in dialog box
1262     * @param button optional second button to add to pane
1263     * @param parent Frame that asked for this dialog
1264     * @param title text do use as title of the dialog box
1265     */
1266    static void makeDialog(Component component, Component button, Frame parent, String title) {
1267        JDialog dialog = new JDialog(parent, title, true);
1268        JButton ok = new JButton(Bundle.getMessage("ButtonOK"));
1269        class myListener implements ActionListener {
1270
1271            java.awt.Window _w;
1272
1273            myListener(java.awt.Window w) {
1274                _w = w;
1275            }
1276
1277            @Override
1278            public void actionPerformed(ActionEvent e) {
1279                // dispose on the GUI thread _later_
1280                ThreadingUtil.runOnGUIEventually( ()->{ 
1281                    _w.dispose();
1282                });
1283            }
1284        }
1285        ok.addActionListener(new myListener(dialog));
1286        ok.setMaximumSize(ok.getPreferredSize());
1287
1288        java.awt.Container contentPane = dialog.getContentPane();
1289        contentPane.setLayout(new BoxLayout(contentPane, BoxLayout.Y_AXIS));
1290        contentPane.add(component, BorderLayout.CENTER);
1291        contentPane.add(Box.createVerticalStrut(5));
1292        contentPane.add(Box.createVerticalGlue());
1293        JPanel panel = new JPanel();
1294        panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));
1295        panel.add(ok);
1296        if (button != null) {
1297            panel.add(Box.createHorizontalStrut(5));
1298            panel.add(button);
1299        }
1300        contentPane.add(panel, BorderLayout.SOUTH);
1301        dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
1302        dialog.setLocationRelativeTo(parent);
1303        dialog.pack();
1304        // dispose on the GUI thread _later_
1305        ThreadingUtil.runOnGUIEventually( ()->{ 
1306            dialog.setVisible(true);
1307        });
1308    }
1309
1310    private final static Logger log = LoggerFactory.getLogger(Maintenance.class);
1311}