001package jmri.jmrit.logixng.util; 002 003import java.util.ArrayList; 004import java.util.List; 005 006import jmri.InstanceManager; 007import jmri.NamedBean; 008import jmri.NamedBeanUsageReport; 009import jmri.Reference; 010import jmri.jmrit.logixng.*; 011 012/** 013 * List the places where an item is used. 014 * 015 * @author Daniel Bergqvist (C) 2023 016 */ 017public class WhereUsed { 018 019 020 private static final String NEW_LINE = System.getProperty("line.separator"); 021 022 private static final String PAD = " "; 023 024 025 private WhereUsed() { 026 } 027 028 029 public static String whereUsed(NamedBean bean) { 030 031 Reference<String> ref = new Reference<>(); 032 033 // Iterate all the LogixNGs 034 InstanceManager.getDefault(LogixNG_Manager.class).getNamedBeanSet().forEach((logixNG) -> { 035 StringBuilder sb = new StringBuilder(); 036 for (int i=0; i < logixNG.getNumConditionalNGs(); i++) { 037 ConditionalNG conditionalNG = logixNG.getConditionalNG(i); 038 String s = checkFemaleSocket(conditionalNG.getFemaleSocket(), bean, conditionalNG, PAD+PAD); 039 if (s != null) { 040 sb.append(PAD); 041 sb.append(conditionalNG.getLongDescription()); 042 sb.append(NEW_LINE); 043 sb.append(s); 044 } 045 } 046 if (sb.length() > 0) { 047 String str = logixNG.getLongDescription() + NEW_LINE + sb.toString() + NEW_LINE; 048 if (ref.get() != null) ref.set(ref.get() + str); 049 else ref.set(str); 050 } 051 }); 052 053 // Iterate all the Modules 054 InstanceManager.getDefault(ModuleManager.class).getNamedBeanSet().forEach((module) -> { 055 String s = checkFemaleSocket(module.getRootSocket(), bean, null, PAD); 056 if (s != null) { 057 String str = module.getLongDescription() + NEW_LINE + s + NEW_LINE; 058 if (ref.get() != null) ref.set(ref.get() + str); 059 else ref.set(str); 060 } 061 }); 062 063 String result = ref.get(); 064 065 // Iterate the Clipboard 066 String s = checkFemaleSocket(InstanceManager.getDefault(LogixNG_Manager.class).getClipboard().getFemaleSocket(), bean, null, PAD); 067 if (s != null) { 068 String str = Bundle.getMessage("Clipboard") + NEW_LINE + s; 069 if (result != null) result += str; 070 else result = str; 071 } 072 073 return result != null ? result : ""; 074 } 075 076 private static String checkFemaleSocket(FemaleSocket femaleSocket, NamedBean bean, ConditionalNG conditionalNG, String pad) { 077 078 if (!femaleSocket.isConnected()) return null; 079 080 Base b = femaleSocket.getConnectedSocket(); 081 082 while (b instanceof MaleSocket) { 083 b = ((MaleSocket)b).getObject(); 084 } 085 086 if (b == null) { 087 throw new UnsupportedOperationException("object is null"); 088 } 089 090 List<NamedBeanUsageReport> report = new ArrayList<>(); 091 b.getUsageDetail(0, bean, report, conditionalNG); 092 093 StringBuilder sb = new StringBuilder(); 094 if (!report.isEmpty()) { 095 sb.append(pad).append(femaleSocket.getLongDescription()).append(NEW_LINE); 096 sb.append(pad).append(PAD).append(b.getLongDescription()).append(" <<====").append(NEW_LINE); 097 pad += PAD; 098 } 099 100 101 String padding = sb.length() > 0 ? pad+PAD : pad+PAD+PAD; 102 103 for (int i=0; i < b.getChildCount(); i++) { 104 String temp = checkFemaleSocket(b.getChild(i), bean, conditionalNG, padding); 105 if (temp != null) { 106 if (sb.length() == 0) { 107 sb.append(pad).append(femaleSocket.getLongDescription()).append(NEW_LINE); 108 sb.append(pad).append(PAD).append(b.getLongDescription()).append(NEW_LINE); 109 pad += PAD; 110 } 111 sb.append(temp); 112 } 113 } 114 115 if (sb.length() > 0) { 116 return sb.toString(); 117 } else { 118 return null; 119 } 120 } 121 122}