001/** 002 * Copyright (c) 2004-2011 QOS.ch 003 * All rights reserved. 004 * 005 * Permission is hereby granted, free of charge, to any person obtaining 006 * a copy of this software and associated documentation files (the 007 * "Software"), to deal in the Software without restriction, including 008 * without limitation the rights to use, copy, modify, merge, publish, 009 * distribute, sublicense, and/or sell copies of the Software, and to 010 * permit persons to whom the Software is furnished to do so, subject to 011 * the following conditions: 012 * 013 * The above copyright notice and this permission notice shall be 014 * included in all copies or substantial portions of the Software. 015 * 016 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 017 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 018 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 019 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 020 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 021 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 022 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 023 * 024 */ 025package org.slf4j.helpers; 026 027import static org.junit.Assert.assertTrue; 028import static org.junit.Assert.fail; 029 030import java.lang.reflect.InvocationHandler; 031import java.lang.reflect.InvocationTargetException; 032import java.lang.reflect.Method; 033import java.lang.reflect.Proxy; 034import java.util.ArrayList; 035import java.util.Arrays; 036import java.util.HashSet; 037import java.util.List; 038import java.util.Set; 039 040import org.junit.Test; 041import org.slf4j.Logger; 042import org.slf4j.event.EventRecodingLogger; 043import org.slf4j.helpers.SubstituteLogger; 044 045/** 046 * @author Chetan Mehrotra 047 */ 048public class SubstitutableLoggerTest { 049 private static final Set<String> EXCLUDED_METHODS = new HashSet<String>(Arrays.asList("getName")); 050 051 @Test 052 public void testDelegate() throws Exception { 053 SubstituteLogger log = new SubstituteLogger("foo", null, false); 054 assertTrue(log.delegate() instanceof EventRecodingLogger); 055 056 Set<String> expectedMethodSignatures = determineMethodSignatures(Logger.class); 057 LoggerInvocationHandler ih = new LoggerInvocationHandler(); 058 Logger proxyLogger = (Logger) Proxy.newProxyInstance(getClass().getClassLoader(), new Class[] { Logger.class }, ih); 059 log.setDelegate(proxyLogger); 060 061 invokeMethods(log); 062 063 // Assert that all methods are delegated 064 expectedMethodSignatures.removeAll(ih.getInvokedMethodSignatures()); 065 if (!expectedMethodSignatures.isEmpty()) { 066 fail("Following methods are not delegated " + expectedMethodSignatures.toString()); 067 } 068 } 069 070 private void invokeMethods(Logger proxyLogger) throws InvocationTargetException, IllegalAccessException { 071 for (Method m : Logger.class.getDeclaredMethods()) { 072 if (!EXCLUDED_METHODS.contains(m.getName())) { 073 m.invoke(proxyLogger, new Object[m.getParameterTypes().length]); 074 } 075 } 076 } 077 078 private class LoggerInvocationHandler implements InvocationHandler { 079 private final Set<String> invokedMethodSignatures = new HashSet<String>(); 080 081 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { 082 invokedMethodSignatures.add(getMethodSignature(method)); 083 if (method.getName().startsWith("is")) { 084 return true; 085 } 086 return null; 087 } 088 089 public Set<String> getInvokedMethodSignatures() { 090 return invokedMethodSignatures; 091 } 092 } 093 094 private static Set<String> determineMethodSignatures(Class<Logger> loggerClass) { 095 Set<String> methodSignatures = new HashSet<String>(); 096 for (Method m : loggerClass.getDeclaredMethods()) { 097 if (!EXCLUDED_METHODS.contains(m.getName())) { 098 methodSignatures.add(getMethodSignature(m)); 099 } 100 } 101 return methodSignatures; 102 } 103 104 private static String getMethodSignature(Method m) { 105 List<String> result = new ArrayList<String>(); 106 result.add(m.getName()); 107 for (Class<?> clazz : m.getParameterTypes()) { 108 result.add(clazz.getSimpleName()); 109 } 110 return result.toString(); 111 } 112}