SocketCollector implements Closeable, Runnable { static String loggerName2Topic(String loggerName) { StringBuilder out = new StringBuilder(); for (int c = 0; c < loggerName.length(); c++) { Character ch = loggerName.charAt(c); if (Character.isDigit(ch) || Character.isLowerCase(ch) || Character.isUpperCase(ch)) { out.append(ch); } else if (ch == '.') { out.append("/"); } } String outSt = out.toString(); while (outSt.length() > 1 && outSt.endsWith("/")) { outSt = outSt.substring(0, outSt.length() - 1); } return "decanter/collect/log/" + outSt.replace(".", "/"); }  @SuppressWarnings("unchecked") @Activate void activate(ComponentContext context); @Override void run(); @Deactivate @Override void close(); static final String PORT_NAME; static final String WORKERS_NAME; @Reference
    public EventAdmin dispatcher; }
@Test public void testLoggerName2Topic() { String topic = SocketCollector.loggerName2Topic("test.[Tomcat].[localhost].[/]"); Assert.assertEquals("decanter/collect/log/test/Tomcat/localhost", topic); }