From 77ede1c3b0e210bceab77dcebb1bf9829372d6bd Mon Sep 17 00:00:00 2001 From: Christian Wulf <chw@informatik.uni-kiel.de> Date: Mon, 3 Nov 2014 08:14:10 +0100 Subject: [PATCH] refactored test --- .../classpath/CachedClassForNameResolver.java | 59 +++++++++++++++++++ .../util/classpath/ClassForNameResolver.java | 48 +++++++++++++++ .../framework/pipe/PipeFactoryLoaderTest.java | 18 +++--- 3 files changed, 115 insertions(+), 10 deletions(-) create mode 100644 src/main/java/teetime/util/classpath/CachedClassForNameResolver.java create mode 100644 src/main/java/teetime/util/classpath/ClassForNameResolver.java diff --git a/src/main/java/teetime/util/classpath/CachedClassForNameResolver.java b/src/main/java/teetime/util/classpath/CachedClassForNameResolver.java new file mode 100644 index 00000000..5989981f --- /dev/null +++ b/src/main/java/teetime/util/classpath/CachedClassForNameResolver.java @@ -0,0 +1,59 @@ +/*************************************************************************** + * Copyright 2014 Kieker Project (http://kieker-monitoring.net) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ***************************************************************************/ + +package teetime.util.classpath; + +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + +/** + * @param <T> + * the type that is used to cast a type that was found in the class path + * + * @author Christian Wulf + * @since 1.11 + */ +public class CachedClassForNameResolver<T> { + + private final ConcurrentMap<String, Class<? extends T>> cachedClasses = new ConcurrentHashMap<String, Class<? extends T>>(); // NOCS + private final ClassForNameResolver<T> classForNameResolver; + + public CachedClassForNameResolver(final ClassForNameResolver<T> classForNameResolver) { + this.classForNameResolver = classForNameResolver; + } + + /** + * This method tries to find a class with the given name. + * + * @param classname + * The name of the class. + * + * @return A {@link Class} instance corresponding to the given name, if it exists. + * + * @throws ClassNotFoundException + */ + public final Class<? extends T> classForName(final String classname) throws ClassNotFoundException { + Class<? extends T> clazz = this.cachedClasses.get(classname); + if (clazz == null) { + clazz = this.classForNameResolver.classForName(classname); + final Class<? extends T> previousClass = this.cachedClasses.putIfAbsent(classname, clazz); + if (null != previousClass) { + clazz = previousClass; + } + } + return clazz; + } +} diff --git a/src/main/java/teetime/util/classpath/ClassForNameResolver.java b/src/main/java/teetime/util/classpath/ClassForNameResolver.java new file mode 100644 index 00000000..86c340e2 --- /dev/null +++ b/src/main/java/teetime/util/classpath/ClassForNameResolver.java @@ -0,0 +1,48 @@ +/*************************************************************************** + * Copyright 2014 Kieker Project (http://kieker-monitoring.net) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ***************************************************************************/ + +package teetime.util.classpath; + +/** + * @param <T> + * the type that is used to cast a type that was found in the class path + * + * @author Christian Wulf + * @since 1.11 + */ +public class ClassForNameResolver<T> { + + private final Class<T> classToCast; + + public ClassForNameResolver(final Class<T> classToCast) { + this.classToCast = classToCast; + } + + /** + * This method tries to find a class with the given name. + * + * @param classname + * The name of the class. + * + * @return A {@link Class} instance corresponding to the given name, if it exists. + * @throws ClassNotFoundException + * + */ + public final Class<? extends T> classForName(final String classname) throws ClassNotFoundException { + final Class<?> clazz = Class.forName(classname); + return clazz.asSubclass(this.classToCast); + } +} diff --git a/src/test/java/teetime/framework/pipe/PipeFactoryLoaderTest.java b/src/test/java/teetime/framework/pipe/PipeFactoryLoaderTest.java index aa289d37..cc6b98f5 100644 --- a/src/test/java/teetime/framework/pipe/PipeFactoryLoaderTest.java +++ b/src/test/java/teetime/framework/pipe/PipeFactoryLoaderTest.java @@ -11,7 +11,10 @@ import java.util.List; import org.junit.Assert; import org.junit.Test; +import teetime.util.classpath.ClassForNameResolver; + public class PipeFactoryLoaderTest { + @Test public void emptyConfig() throws IOException { List<IPipeFactory> list = PipeFactoryLoader.loadPipeFactoriesFromClasspath("data/empty-test.conf"); @@ -44,16 +47,17 @@ public class PipeFactoryLoaderTest { // Second part of the test: PipeFactoryRegistry PipeFactoryRegistry pipeRegistry = PipeFactoryRegistry.INSTANCE; + ClassForNameResolver<IPipeFactory> classResolver = new ClassForNameResolver<IPipeFactory>(IPipeFactory.class); // Look for the "normal" pipes - for (String string : readConf(pipeConfig)) { - IPipeFactory pipeFactory = getClassByString(string); + for (String className : readConf(pipeConfig)) { + IPipeFactory pipeFactory = classResolver.classForName(className).newInstance(); IPipeFactory returnedFactory = pipeRegistry.getPipeFactory(pipeFactory.getThreadCommunication(), pipeFactory.getOrdering(), pipeFactory.isGrowable()); Assert.assertEquals(pipeFactory.getClass().getCanonicalName(), returnedFactory.getClass().getCanonicalName()); } // Second "and a half" part - for (String string : readConf(testConfig)) { - IPipeFactory pipeFactory = getClassByString(string); + for (String className : readConf(testConfig)) { + IPipeFactory pipeFactory = classResolver.classForName(className).newInstance(); // Still old factory IPipeFactory returnedFactory = pipeRegistry.getPipeFactory(pipeFactory.getThreadCommunication(), pipeFactory.getOrdering(), pipeFactory.isGrowable()); Assert.assertNotEquals(pipeFactory.getClass().getCanonicalName(), returnedFactory.getClass().getCanonicalName()); @@ -64,12 +68,6 @@ public class PipeFactoryLoaderTest { } } - private IPipeFactory getClassByString(final String string) throws ClassNotFoundException, InstantiationException, IllegalAccessException { - Class<?> clazz = Class.forName(string); - Class<? extends IPipeFactory> pipeFactoryClass = clazz.asSubclass(IPipeFactory.class); - return pipeFactoryClass.newInstance(); - } - private int countLines(final File fileName) throws IOException { BufferedReader fileReader = new BufferedReader(new FileReader(fileName)); int lines = 0;// NOPMD -- GitLab