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