LoggingPlugin implements C10NPlugin { @Override public PluginResult format(String resolvedMessage, Object resolvedReturnValue, InvocationDetails invocationDetails) { Class<?> c10nInterface = invocationDetails.getC10nInterface(); if (null == c10nInterface.getAnnotation(Logger.class)) { return PluginResult.passOn(resolvedReturnValue); } Method method = invocationDetails.getMethod(); Object[] methodArgs = invocationDetails.getMethodArguments(); if (method.getDeclaringClass().equals(LoggingBase.class)) { try { return PluginResult.last(method.invoke(implementation, methodArgs)); } catch (IllegalAccessException | InvocationTargetException e) { throw new RuntimeException("Failed to invoke metod '" + method.getName() + "' on current logger implementation instance.", e); } } LoggingLevel level = get(c10nInterface, method, Level.class, defaultLoggingLevel, Level::value); String loggerName = get(c10nInterface, method, Logger.class, c10nInterface.getName(), (logger) -> { if (!logger.name().equals(Logger.NO_LOGGER_NAME)) { return logger.name(); } if (!logger.value().equals(Logger.class)) { return logger.value().getName(); } return c10nInterface.getName(); }); implementation.log(loggerName, level, String.valueOf(resolvedMessage), getCauseOrNull(methodArgs), invocationDetails); return PluginResult.last(null); } LoggingPlugin();  LoggingPlugin(LoggingLevel defaultLoggingLevel, LoggerImplementation implementation); @Override PluginResult format(String resolvedMessage,
                               Object resolvedReturnValue,
                               InvocationDetails invocationDetails);  }
@Test public void loggingRequestsInterruptThePluginPipeline() throws Exception { LoggerImplementation logger = Mockito.mock(LoggerImplementation.class); LoggingPlugin plugin = new LoggingPlugin(LoggingLevel.INFO, logger); PluginResult res = plugin.format("test message", "test message", new InvocationDetails(null, LoggingMessagesWithClassDecls.class, TestUtil.method(LoggingMessagesWithClassDecls.class, "usesClassLogger"), null)); assertThat(res.isInterrupt(), is(equalTo(true))); }
@Test public void unrelatedC10NMessageClassesAreNotPassedThroughThePlugin() { LoggerImplementation logger = Mockito.mock(LoggerImplementation.class); LoggingPlugin plugin = new LoggingPlugin(LoggingLevel.INFO, logger); PluginResult res = plugin.format("noArg", "noArg", new InvocationDetails(null, UnrelatedC10NMessageBundle.class, TestUtil.method(UnrelatedC10NMessageBundle.class, "noArg"), null)); assertThat(res.isInterrupt(), is(equalTo(false))); assertThat(res.getValue(), is(equalTo("noArg"))); verifyZeroInteractions(logger); }
@Test public void extendingLoggerBaseGainsAccessToUnderlyingLoggerFunctionality() throws Exception { LoggerImplementation logger = Mockito.mock(LoggerImplementation.class); when(logger.isDebugEnabled()).thenReturn(true); when(logger.isLevelEnabled(any(LoggingLevel.class))).thenReturn(false); LoggingPlugin plugin = new LoggingPlugin(LoggingLevel.INFO, logger); PluginResult res = plugin.format(null, null, new InvocationDetails(null, WithUtils.class, TestUtil.method(LoggingBase.class, "isDebugEnabled"), null)); assertThat(res.isInterrupt(), is(equalTo(true))); assertThat(res.getValue(), is(equalTo(true))); PluginResult res2 = plugin.format(null, null, new InvocationDetails(null, WithUtils.class, TestUtil.method(LoggingBase.class, "isLevelEnabled"), new Object[]{LoggingLevel.ERROR})); assertThat(res2.isInterrupt(), is(equalTo(true))); assertThat(res2.getValue(), is(equalTo(false))); verify(logger).isLevelEnabled(LoggingLevel.ERROR); }