/* * #%L * ===================================================== * _____ _ ____ _ _ _ _ * |_ _|_ __ _ _ ___| |_ / __ \| | | | ___ | | | | * | | | '__| | | / __| __|/ / _` | |_| |/ __|| |_| | * | | | | | |_| \__ \ |_| | (_| | _ |\__ \| _ | * |_| |_| \__,_|___/\__|\ \__,_|_| |_||___/|_| |_| * \____/ * * ===================================================== * * Hochschule Hannover * (University of Applied Sciences and Arts, Hannover) * Faculty IV, Dept. of Computer Science * Ricklinger Stadtweg 118, 30459 Hannover, Germany * * Email: trust@f4-i.fh-hannover.de * Website: http://trust.f4.hs-hannover.de/ * * This file is part of visitmeta-common, version 0.6.0, * implemented by the Trust@HsH research group at the Hochschule Hannover. * %% * Copyright (C) 2012 - 2016 Trust@HsH * %% * 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. * #L% */ package de.hshannover.f4.trust.visitmeta.util; import java.io.FileInputStream; import java.io.IOException; import java.net.URL; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; import org.apache.log4j.Logger; /** * Utility class for Reflection operations. * * @author Bastian Hellmann * */ public class ReflectionUtils { private static Logger logger = Logger.getLogger(ReflectionUtils.class); /** * Checks a list of given class names if they implement a given interface * and loads it via reflection. * * @param classLoader * a given {@link ClassLoader} instance (configured with specific * URLs for JARs etc.) * @param classNames * a {@link List} of class names * @param t * a {@link Class} that specifies a interface class * @return a fresh instance of the class type given as parameter; * <b<null</b> if no class was found */ @SuppressWarnings("unchecked") public static <T> T loadClass(ClassLoader classLoader, List<String> classNames, Class<T> t) { for (String className : classNames) { try { Class<?> classToLoad = Class.forName(className, true, classLoader); Class<?>[] interfaces = classToLoad.getInterfaces(); boolean implementsInterface = false; for (Class<?> i : interfaces) { if (i.getCanonicalName().equals(t.getCanonicalName())) { implementsInterface = true; } } if (implementsInterface) { logger.trace(className + " implements " + t.getCanonicalName()); return (T) classToLoad.newInstance(); } else { logger.trace(className + " does not implement " + t.getCanonicalName()); } } catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) { logger.warn("could not load " + className + ": " + e); } } return null; } /** * Creates a {@link List} of all classes within a given JAR file. * * From: * http://stackoverflow.com/questions/15720822/how-to-get-names-of-classes * -inside-a-jar-file * * @param jarFile * the JAR file to search for Classes * @return a {@link List} with all found classes * @throws IOException */ public static List<String> getClassNames(URL jarFile) throws IOException { List<String> classNames = new ArrayList<String>(); ZipInputStream zip = new ZipInputStream(new FileInputStream( jarFile.getPath())); for (ZipEntry entry = zip.getNextEntry(); entry != null; entry = zip .getNextEntry()) { if (entry.getName().endsWith(".class") && !entry.isDirectory()) { // This ZipEntry represents a class. Now, what class does it // represent? StringBuilder className = new StringBuilder(); for (String part : entry.getName().split("/")) { if (className.length() != 0) { className.append("."); } className.append(part); if (part.endsWith(".class")) { className.setLength(className.length() - ".class".length()); } } classNames.add(className.toString()); } } zip.close(); return classNames; } /** * Checks if a given class implements a given interface. * * @param givenClass * a class * @param interfaceClass * a class specifying an interface * @return true, if the givenClass implements the interface */ public static boolean implementsInterface(Class<?> givenClass, Class<?> interfaceClass) { List<Class<?>> interfacesList = Arrays.asList(givenClass .getInterfaces()); if (interfacesList != null && interfacesList.contains(interfaceClass)) { return true; } else { return false; } } }