001package jmri.jmrit.whereused; 002 003import jmri.jmrit.blockboss.BlockBossLogicProvider; 004import jmri.jmrit.display.EditorManager; 005 006import java.util.Collections; 007import java.util.Enumeration; 008 009import jmri.*; 010import jmri.jmrit.blockboss.BlockBossLogic; 011import jmri.jmrit.ctc.CtcManager; 012import jmri.jmrit.display.switchboardEditor.SwitchboardEditor; 013import jmri.jmrit.entryexit.EntryExitPairs; 014import jmri.jmrit.logix.OBlockManager; 015import jmri.jmrit.logix.WarrantManager; 016import jmri.jmrit.logixng.LogixNG_Manager; 017import jmri.jmrit.logixng.ModuleManager; 018import jmri.jmrit.display.layoutEditor.LayoutBlockManager; 019/** 020 * Find references. Each collector method calls a corresponding getUsageReport(NamedBean) 021 * in the main implementation class for the object type. The matches are returned in an 022 * array list of NamedBeanUsageReport objects. 023 * 024 * Collectors: 025 * <ul> 026 * <li>checkAudio</li> 027 * <li>checkTurnouts</li> 028 * <li>checkLights</li> 029 * <li>checkRoutes</li> 030 * <li>checkBlocks</li> 031 * <li>checkLayoutBlocks</li> 032 * <li>checkSignalHeadLogic</li> 033 * <li>checkSignalMastLogic</li> 034 * <li>checkSignalGroups</li> 035 * <li>checkOBlocks</li> 036 * <li>checkWarrants</li> 037 * <li>checkEntryExit</li> 038 * <li>checkLogixConditionals</li> 039 * <li>checkLogixNGConditionals</li> 040 * <li>checkSections</li> 041 * <li>checkTransits</li> 042 * <li>checkPanels</li> 043 * <li>checkCTC</li> 044 * </ul> 045 * 046 * @author Dave Sand Copyright (C) 2020 047 */ 048 049public class WhereUsedCollectors { 050 051 /** 052 * Create the Audio usage string. 053 * Usage keys: 054 * <ul> 055 * <li>AudioBuffer</li> 056 * </ul> 057 * @param bean The requesting bean: Audio. 058 * @return usage string 059 */ 060 static String checkAudio(NamedBean bean) { 061 StringBuilder sb = new StringBuilder(); 062 InstanceManager.getDefault(AudioManager.class).getNamedBeanSet().forEach((audio) -> audio.getUsageReport(bean).forEach((report) -> { 063 if (report.usageKey.startsWith("Audio")) { // NOI18N 064 String name = audio.getDisplayName(NamedBean.DisplayOptions.USERNAME_SYSTEMNAME); 065 sb.append(Bundle.getMessage("ReferenceLineName", name)); // NOI18N 066 } 067 })); 068 return addHeader(sb, "ReferenceAudio"); // NOI18N 069 } 070 071 /** 072 * Create the Turnout usage string. 073 * Usage keys: 074 * <ul> 075 * <li>TurnoutFeedback1</li> 076 * <li>TurnoutFeedback2</li> 077 * </ul> 078 * @param bean The requesting bean: Sensor. 079 * @return usage string 080 */ 081 static String checkTurnouts(NamedBean bean) { 082 StringBuilder sb = new StringBuilder(); 083 InstanceManager.getDefault(TurnoutManager.class).getNamedBeanSet().forEach((turnout) -> { 084 int feedback = turnout.getFeedbackMode(); 085 if (feedback == Turnout.ONESENSOR || feedback == Turnout.TWOSENSOR) { 086 turnout.getUsageReport(bean).forEach((report) -> { 087 if (report.usageKey.startsWith("TurnoutFeedback")) { // NOI18N 088 String name = turnout.getDisplayName(NamedBean.DisplayOptions.USERNAME_SYSTEMNAME); 089 sb.append(Bundle.getMessage("ReferenceLineName", name)); // NOI18N 090 } 091 }); 092 } 093 }); 094 return addHeader(sb, "ReferenceFeedback"); // NOI18N 095 } 096 097 /** 098 * Create the Light usage string. 099 * Usage keys: 100 * <ul> 101 * <li>LightControlSensor1</li> 102 * <li>LightControlSensor2</li> 103 * <li>LightControlSensorTimed</li> 104 * <li>LightControlTurnout</li> 105 * </ul> 106 * @param bean The requesting bean: Sensor, Turnout. 107 * @return usage string 108 */ 109 static String checkLights(NamedBean bean) { 110 StringBuilder sb = new StringBuilder(); 111 InstanceManager.getDefault(LightManager.class).getNamedBeanSet().forEach((light) -> light.getUsageReport(bean).forEach((report) -> { 112 if (report.usageKey.startsWith("LightControl")) { // NOI18N 113 String name = light.getDisplayName(NamedBean.DisplayOptions.USERNAME_SYSTEMNAME); 114 sb.append(Bundle.getMessage("ReferenceLineData", name, report.usageData)); // NOI18N 115 } 116 })); 117 return addHeader(sb, "ReferenceLightControl"); // NOI18N 118 } 119 120 /** 121 * Create the Route usage string. 122 * Usage keys: 123 * <ul> 124 * <li>RouteTurnoutOutput</li> 125 * <li>RouteSensorOutput</li> 126 * <li>RouteSensorControl</li> 127 * <li>RouteSensorAligned</li> 128 * <li>RouteTurnoutControl</li> 129 * <li>RouteTurnoutLock</li> 130 * </ul> 131 * @param bean The requesting bean: Sensor, Turnout. 132 * @return usage string 133 */ 134 static String checkRoutes(NamedBean bean) { 135 StringBuilder sb = new StringBuilder(); 136 InstanceManager.getDefault(RouteManager.class).getNamedBeanSet().forEach((route) -> route.getUsageReport(bean).forEach((report) -> { 137 if (report.usageKey.startsWith("Route")) { // NOI18N 138 String name = route.getDisplayName(NamedBean.DisplayOptions.USERNAME_SYSTEMNAME); 139 sb.append(Bundle.getMessage("ReferenceLineName", name)); // NOI18N 140 } 141 })); 142 return addHeader(sb, "ReferenceRoutes"); // NOI18N 143 } 144 145 /** 146 * Create the Block usage string. 147 * Usage keys: 148 * <ul> 149 * <li>BlockSensor</li> 150 * <li>BlockReporter</li> 151 * <li>BlockPathNeighbor</li> 152 * <li>BlockPathTurnout</li> 153 * </ul> 154 * @param bean The requesting bean: Block (Path neighbor), Sensor, Reporter, Turnout (Path). 155 * @return usage string 156 */ 157 static String checkBlocks(NamedBean bean) { 158 StringBuilder sb = new StringBuilder(); 159 InstanceManager.getDefault(BlockManager.class).getNamedBeanSet().forEach((block) -> block.getUsageReport(bean).forEach((report) -> { 160 if (report.usageKey.startsWith("Block")) { // NOI18N 161 String name = block.getDisplayName(NamedBean.DisplayOptions.USERNAME_SYSTEMNAME); 162 sb.append(Bundle.getMessage("ReferenceLineName", name)); // NOI18N 163 } 164 })); 165 return addHeader(sb, "ReferenceBlock"); // NOI18N 166 } 167 168 /** 169 * Create the LayoutBlock usage string. 170 * Usage keys: 171 * <ul> 172 * <li>LayoutBlockBlock</li> 173 * <li>LayoutBlockMemory</li> 174 * <li>LayoutBlockSensor</li> 175 * <li>LayoutBlockNeighbor</li> 176 * </ul> 177 * @param bean The requesting bean: Block, Memory, Sensor. 178 * @return usage string 179 */ 180 static String checkLayoutBlocks(NamedBean bean) { 181 StringBuilder sb = new StringBuilder(); 182 InstanceManager.getDefault(LayoutBlockManager.class).getNamedBeanSet().forEach((layoutBlock) -> layoutBlock.getUsageReport(bean).forEach((report) -> { 183 if (report.usageKey.startsWith("LayoutBlock")) { // NOI18N 184 String name = layoutBlock.getDisplayName(NamedBean.DisplayOptions.USERNAME_SYSTEMNAME); 185 sb.append(Bundle.getMessage("ReferenceLineData", name, report.usageData)); // NOI18N 186 } 187 })); 188 return addHeader(sb, "ReferenceLayoutBlock"); // NOI18N 189 } 190 191 /** 192 * Create the Signal Head Logic usage string. 193 * Usage keys: 194 * <ul> 195 * <li>SSLSignal</li> 196 * <li>SSLSensor1-5</li> 197 * <li>SSLTurnout</li> 198 * <li>SSLSignal1</li> 199 * <li>SSLSignal1Alt</li> 200 * <li>SSLSignal2</li> 201 * <li>SSLSignal2Alt</li> 202 * <li>SSLSensorWatched1</li> 203 * <li>SSLSensorWatched1Alt</li> 204 * <li>SSLSensorWatched2</li> 205 * <li>SSLSensorWatched2Alt</li> 206 * <li>SSLSensorApproach</li> 207 * </ul> 208 * @param bean The requesting bean: Sensor, Signal Head, Turnout. 209 * @return usage string 210 */ 211 static String checkSignalHeadLogic(NamedBean bean) { 212 StringBuilder sb = new StringBuilder(); 213 Enumeration<BlockBossLogic> e = Collections.enumeration(InstanceManager.getDefault(BlockBossLogicProvider.class).provideAll()); 214 while (e.hasMoreElements()) { 215 BlockBossLogic ssl = e.nextElement(); 216 ssl.getUsageReport(bean).forEach((report) -> { 217 if (report.usageKey.startsWith("SSL")) { // NOI18N 218 String name = report.usageBean.getDisplayName(NamedBean.DisplayOptions.USERNAME_SYSTEMNAME); 219 sb.append(Bundle.getMessage("ReferenceLineName", name)); // NOI18N 220 } 221 }); 222 } 223 return addHeader(sb, "ReferenceHeadSSL"); // NOI18N 224 } 225 226 /** 227 * Create the Signal Mast Logic usage string. 228 * Usage keys: 229 * <ul> 230 * <li>SMLSourceMast</li> 231 * <li>SMLDestinationMast</li> 232 * <li>SMLBlockAuto</li> 233 * <li>SMLBlockUser</li> 234 * <li>SMLTurnoutAuto</li> 235 * <li>SMLTurnoutUser</li> 236 * <li>SMLSensor</li> 237 * <li>SMLMastAuto</li> 238 * <li>SMLMastUser</li> 239 * </ul> 240 * @param bean The requesting bean: Block, Turnout, Sensor, Signal Mast. 241 * @return usage string 242 */ 243 static String checkSignalMastLogic(NamedBean bean) { 244 StringBuilder sb = new StringBuilder(); 245 InstanceManager.getDefault(SignalMastLogicManager.class).getNamedBeanSet().forEach((sml) -> sml.getUsageReport(bean).forEach((report) -> { 246 String name = bean.getDisplayName(NamedBean.DisplayOptions.USERNAME_SYSTEMNAME); 247 if (report.usageKey.startsWith("SMLSource")) { // NOI18N 248 sb.append(Bundle.getMessage("ReferenceLineData", name, Bundle.getMessage("SourceMast"))); // NOI18N 249 return; 250 } 251 if (report.usageKey.startsWith("SMLDest")) { // NOI18N 252 sb.append(Bundle.getMessage("ReferenceLineData", name, Bundle.getMessage("DestMast"))); // NOI18N 253 return; 254 } 255 if (report.usageKey.startsWith("SML")) { // NOI18N 256 sb.append(Bundle.getMessage("ReferenceLinePair", sml.getSourceMast().getDisplayName(), report.usageBean.getDisplayName())); // NOI18N 257 } 258 })); 259 return addHeader(sb, "ReferenceMastSML"); // NOI18N 260 } 261 262 /** 263 * Create the Signal Group usage string. 264 * Usage keys: 265 * <ul> 266 * <li>SignalGroupMast</li> 267 * <li>SignalGroupHead</li> 268 * <li>SignalGroupHeadSensor</li> 269 * <li>SignalGroupHeadTurnout</li> 270 * </ul> 271 * @param bean The requesting bean: Sensor, Signal Head, Signal Mast, Turnout. 272 * @return usage string 273 */ 274 static String checkSignalGroups(NamedBean bean) { 275 StringBuilder sb = new StringBuilder(); 276 InstanceManager.getDefault(SignalGroupManager.class).getNamedBeanSet().forEach((group) -> group.getUsageReport(bean).forEach((report) -> { 277 if (report.usageKey.startsWith("SignalGroup")) { // NOI18N 278 String name = group.getDisplayName(NamedBean.DisplayOptions.USERNAME_SYSTEMNAME); 279 sb.append(Bundle.getMessage("ReferenceLineName", name)); // NOI18N 280 } 281 })); 282 return addHeader(sb, "ReferenceSignalGroup"); // NOI18N 283 } 284 285 /** 286 * Create the OBlock usage string. 287 * Usage keys: 288 * <ul> 289 * <li>OBlockSensor</li> 290 * <li>OBlockSensorError</li> 291 * <li>OBlockPortalNeighborOBlock</li> 292 * <li>OBlockPortalSignal</li> 293 * <li>OBlockPortalPathTurnout</li> 294 * <li>OBlockWarrant</li> 295 * </ul> 296 * @param bean The requesting bean: OBlock (Neightbor), Sensor, SignalHead, SignalMast, Turnout, Warrant. 297 * @return usage string 298 */ 299 static String checkOBlocks(NamedBean bean) { 300 StringBuilder sb = new StringBuilder(); 301 InstanceManager.getDefault(OBlockManager.class).getNamedBeanSet().forEach((oblock) -> oblock.getUsageReport(bean).forEach((report) -> { 302 if (report.usageKey.startsWith("OBlock")) { // NOI18N 303 String name = oblock.getDisplayName(NamedBean.DisplayOptions.USERNAME_SYSTEMNAME); 304 sb.append(Bundle.getMessage("ReferenceLineData", name, report.usageData)); // NOI18N 305 } 306 })); 307 return addHeader(sb, "ReferenceOBlock"); // NOI18N 308 } 309 310 /** 311 * Create the Warrant usage string. 312 * Usage keys: 313 * <ul> 314 * <li>WarrantBlocking</li> 315 * <li>WarrantBlock</li> 316 * <li>WarrantSignal</li> 317 * </ul> 318 * @param bean The requesting bean: OBlock SignalHead, SignalMast, Warrant. 319 * @return usage string 320 */ 321 static String checkWarrants(NamedBean bean) { 322 StringBuilder sb = new StringBuilder(); 323 InstanceManager.getDefault(WarrantManager.class).getNamedBeanSet().forEach((warrant) -> warrant.getUsageReport(bean).forEach((report) -> { 324 if (report.usageKey.startsWith("Warrant")) { // NOI18N 325 String name = warrant.getDisplayName(NamedBean.DisplayOptions.USERNAME_SYSTEMNAME); 326 sb.append(Bundle.getMessage("ReferenceLineName", name)); // NOI18N 327 } 328 })); 329 return addHeader(sb, "ReferenceWarrant"); // NOI18N 330 } 331 332 /** 333 * Create the Entry/Exit usage string. 334 * Usage keys: 335 * <ul> 336 * <li>EntryExitSourceSensor</li> 337 * <li>EntryExitSourceSignal</li> 338 * <li>EntryExitDestinationSensor</li> 339 * <li>EntryExitDestinationSignal</li> 340 * </ul> 341 * @param bean The requesting bean: Sensor SignalHead, SignalMast. 342 * @return usage string 343 */ 344 static String checkEntryExit(NamedBean bean) { 345 StringBuilder sb = new StringBuilder(); 346 InstanceManager.getDefault(EntryExitPairs.class).getNamedBeanSet().forEach((destPoint) -> destPoint.getUsageReport(bean).forEach((report) -> { 347 if (report.usageKey.startsWith("EntryExit")) { // NOI18N 348 String name = destPoint.getDisplayName(); 349 sb.append(Bundle.getMessage("ReferenceLineName", name)); // NOI18N 350 } 351 })); 352 return addHeader(sb, "ReferenceEntryExit"); // NOI18N 353 } 354 355 /** 356 * Create the Logix/Conditional usage string. 357 * Usage keys: 358 * <ul> 359 * <li>ConditionalAction</li> 360 * <li>ConditionalVariable</li> 361 * <li>ConditionalVariableData</li> 362 * </ul> 363 * @param bean The requesting bean: Many. 364 * @return usage string 365 */ 366 static String checkLogixConditionals(NamedBean bean) { 367 StringBuilder sb = new StringBuilder(); 368 InstanceManager.getDefault(LogixManager.class).getNamedBeanSet().forEach((logix) -> logix.getUsageReport(bean).forEach((report) -> { 369 if (report.usageKey.startsWith("ConditionalVariable") || report.usageKey.startsWith("ConditionalAction")) { // NOI18N 370 String name = logix.getDisplayName(NamedBean.DisplayOptions.USERNAME_SYSTEMNAME); 371 String cdlName = report.usageBean.getDisplayName(); 372 sb.append(Bundle.getMessage("ReferenceLineConditional", name, cdlName, Bundle.getMessage(report.usageKey), report.usageData)); // NOI18N 373 } 374 })); 375 return addHeader(sb, "ReferenceConditionals"); // NOI18N 376 } 377 378 /** 379 * Create the LogixNG/ConditionalNG usage string. 380 * Usage keys: 381 * <ul> 382 * <li>LogixNGAction</li> 383 * <li>LogixNGExpression</li> 384 * </ul> 385 * @param bean The requesting bean: Many. 386 * @return usage string 387 */ 388 static String checkLogixNGConditionals(NamedBean bean) { 389 StringBuilder sb = new StringBuilder(); 390 InstanceManager.getDefault(LogixNG_Manager.class).getNamedBeanSet().forEach((logixng) -> logixng.getUsageReport(bean).forEach((report) -> { 391 if (report.usageKey.startsWith("LogixNG")) { // NOI18N 392 String name = logixng.getDisplayName(NamedBean.DisplayOptions.USERNAME_SYSTEMNAME); 393 String cdlName = report.usageBean != null ? report.usageBean.getDisplayName() : ""; 394 sb.append(Bundle.getMessage("ReferenceLineLogixNG", name, cdlName, Bundle.getMessage(report.usageKey), report.usageData)); // NOI18N 395 } 396 })); 397 InstanceManager.getDefault(ModuleManager.class).getNamedBeanSet().forEach((module) -> module.getUsageReport(bean).forEach((report) -> { 398 if (report.usageKey.startsWith("LogixNG")) { // NOI18N 399 String name = module.getDisplayName(NamedBean.DisplayOptions.USERNAME_SYSTEMNAME); 400 sb.append(Bundle.getMessage("ReferenceLineModule", name, Bundle.getMessage(report.usageKey), report.usageData)); // NOI18N 401 } 402 })); 403 return addHeader(sb, "ReferenceLogixNG"); // NOI18N 404 } 405 406 /** 407 * Create the Section usage string. 408 * Usage keys: 409 * <ul> 410 * <li>SectionBlock</li> 411 * <li>SectionSensorForwardBlocking</li> 412 * <li>SectionSensorForwardStopping</li> 413 * <li>SectionSensorReverseBlocking</li> 414 * <li>SectionSensorReverseStopping</li> 415 * </ul> 416 * @param bean The requesting bean: Block, Sensor. 417 * @return usage string 418 */ 419 static String checkSections(NamedBean bean) { 420 StringBuilder sb = new StringBuilder(); 421 InstanceManager.getDefault(SectionManager.class).getNamedBeanSet().forEach((section) -> section.getUsageReport(bean).forEach((report) -> { 422 if (report.usageKey.startsWith("SectionSensor")) { // NOI18N 423 String name = section.getDisplayName(NamedBean.DisplayOptions.USERNAME_SYSTEMNAME); 424 sb.append(Bundle.getMessage("ReferenceLineName", name)); // NOI18N 425 } 426 })); 427 return addHeader(sb, "ReferenceSections"); // NOI18N 428 } 429 430 /** 431 * Create the Transit usage string. 432 * Usage keys: 433 * <ul> 434 * <li>TransitSection</li> 435 * <li>TransitSensorStopAllocation</li> 436 * <li>TransitActionSensorWhen</li> 437 * <li>TransitActionSensorWhat</li> 438 * <li>TransitActionSignalHeadWhat</li> 439 * <li>TransitActionSignalMastWhat</li> 440 * </ul> 441 * @param bean The requesting bean: Section, Sensor, Signal Head, Signal Mast. 442 * @return usage string 443 */ 444 static String checkTransits(NamedBean bean) { 445 StringBuilder sb = new StringBuilder(); 446 InstanceManager.getDefault(TransitManager.class).getNamedBeanSet().forEach((transit) -> transit.getUsageReport(bean).forEach((report) -> { 447 String name = transit.getDisplayName(NamedBean.DisplayOptions.USERNAME_SYSTEMNAME); 448 if (report.usageKey.startsWith("TransitSensor") || report.usageKey.startsWith("TransitSection")) { // NOI18N 449 sb.append(Bundle.getMessage("ReferenceLineName", name)); // NOI18N 450 } 451 if (report.usageKey.startsWith("TransitAction")) { // NOI18N 452 sb.append(Bundle.getMessage("ReferenceLineAction", name, report.usageBean.getDisplayName())); // NOI18N 453 } 454 })); 455 return addHeader(sb, "ReferenceTransits"); // NOI18N 456 } 457 458 /** 459 * Create the Panel usage string. The string includes the icon class name. 460 * Usage keys: 461 * <ul> 462 * <li>PositionalIcon</li> 463 * <li>LayoutEditorTurnout</li> 464 * <li>LayoutEditorTurnout2</li> 465 * <li>LayoutEditorTurnoutBlock</li> 466 * <li>LayoutEditorTurnoutSensor</li> 467 * <li>LayoutEditorTurnoutSignalHead</li> 468 * <li>LayoutEditorTurnoutSignalMast</li> 469 * <li>LayoutEditorPointSensor</li> 470 * <li>LayoutEditorPointSignalHead</li> 471 * <li>LayoutEditorPointSignalMast</li> 472 * <li>LayoutEditorSegmentBlock</li> 473 * <li>LayoutEditorXingBlock</li> 474 * <li>LayoutEditorXingOther (sensor, head, mast)</li> 475 * <li>Switchboard (sensor, turnout, light)</li> 476 * </ul> 477 * Note: The getUsageReport is invoked at either Editor or LayoutEditor depending on the 478 * panel type. The LayoutEditor version does a super call and then does special turnout 479 * checking since LE turnouts are not icons. 480 * @param bean The requesting bean: Many. 481 * @return usage string 482 */ 483 static String checkPanels(NamedBean bean) { 484 StringBuilder sb = new StringBuilder(); 485 InstanceManager.getDefault(EditorManager.class).getAll().forEach(panel -> 486 panel.getUsageReport(bean).forEach(report -> { 487 if (panel instanceof SwitchboardEditor) { 488 sb.append(Bundle.getMessage("ReferenceLineName", report.usageData)); // NOI18N 489 } else { 490 sb.append(Bundle.getMessage("ReferenceLinePanel", panel.getTitle(), report.usageData)); // NOI18N 491 } 492 })); 493 return addHeader(sb, "ReferencePanels"); // NOI18N 494 } 495 496 /** 497 * Create the CTC usage string. 498 * The CTC manager is found using the ConfigureManager instead of the InstanceManager. 499 * The CTC manager uses InstanceManagerAutoDefault which can result in unnecessary 500 * XML content when CTC is not being used. 501 * Usage keys: 502 * <ul> 503 * <li>CtcWhereUsedOther</li> 504 * <li>CtcWhereUsedCBHD</li> 505 * </ul> 506 * @param bean The requesting bean: Block, Sensor, Signal Head, Signal Mast, Turnout. 507 * @return usage string 508 */ 509 static String checkCTC(NamedBean bean) { 510 StringBuilder sb = new StringBuilder(); 511 512 // Get the CTC manager via the ConfigureManager to avoid auto default. 513 InstanceManager.getOptionalDefault(ConfigureManager.class).ifPresent(cm -> { 514 cm.getInstanceList(CtcManager.class).forEach(m -> { 515 mgr = (CtcManager) m; 516 }); 517 }); 518 519 if (mgr != null) { 520 mgr.getUsageReport(bean).forEach((report) -> { 521 sb.append(Bundle.getMessage("ReferenceLineName", report.usageData)); // NOI18N 522 }); 523 } 524 return addHeader(sb, "ReferenceCTC"); // NOI18N 525 } 526 static CtcManager mgr = null; 527 528 /** 529 * Add the specified section to the beginning of the string builder if there is data. 530 * @param sb The current string builder. 531 * @param bundleKey The key for the section header. 532 * @return the resulting string. 533 */ 534 static String addHeader(StringBuilder sb, String bundleKey) { 535 if (sb.length() > 0) { 536 sb.insert(0, Bundle.getMessage("ReferenceHeader", Bundle.getMessage(bundleKey))); // NOI18N 537 sb.append("\n"); 538 } 539 return sb.toString(); 540 } 541 542// private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(WhereUsedCollectors.class); 543}