aboutsummaryrefslogtreecommitdiffstats
path: root/asdctool/src/test/java/org/openecomp/sdc/asdctool/migration/scanner/ClassScanner.java
blob: 38cf068cbb86ea9f88c53f7499a3bdfd198ed448 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
package org.openecomp.sdc.asdctool.migration.scanner;

import org.apache.commons.io.FileUtils;
import org.openecomp.sdc.asdctool.migration.core.MigrationException;

import java.io.File;
import java.lang.reflect.Modifier;
import java.net.URL;
import java.util.*;

/**
 * scan and instantiate classes of given type in the class path
 */
public class ClassScanner {


    private ClassLoader classLoader = Thread.currentThread().getContextClassLoader();

    public <T> List<T> getAllClassesOfType(String basePackage, Class<T> ofType) {
        Collection<File> allClassesInPackage = getAllClassesInPackage(basePackage);
        List<T> loadedClasses = new ArrayList<>();
        for (File clazzFile : allClassesInPackage) {
            Optional<T> instance = loadAndInstantiateClass(getClassReference(clazzFile), ofType);
            instance.ifPresent(loadedClasses::add);
        }
        return loadedClasses;
    }

    private <T> Optional<T> loadAndInstantiateClass(String classReference, Class<T> ofType)  {
        try {
            return instantiateClassOfType(classReference, ofType);
        }catch (ClassNotFoundException e) {
            //log
            throw new MigrationException(String.format("could not find class %s of type %s. cause: %s", classReference, ofType.toGenericString(), e.getMessage()));
        } catch (IllegalAccessException e1) {
            //log
            throw new MigrationException(String.format("could not instantiate class %s of type %s. class is not accessible. cause: %s", classReference, ofType.toGenericString(), e1.getMessage()));
        } catch (InstantiationException e2) {
            //log
            throw new MigrationException(String.format("could not instantiate class %s of type %s. cause: %s", classReference, ofType.toGenericString(), e2.getMessage()));
        }
    }

    private <T> Optional<T> instantiateClassOfType(String classReference, Class<T> ofType) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
        String className = classReference.replaceAll(".class$", "").replaceAll(".class", "");
        Class<?> aClass = classLoader.loadClass(className);
        if (ofType.isAssignableFrom(aClass) && isInstantiateAbleClass(aClass)){
            return Optional.of((T) aClass.newInstance());
        }
        return Optional.empty();
    }

    private boolean isInstantiateAbleClass(Class<?> clazz) {
        return !Modifier.isAbstract(clazz.getModifiers()) && !clazz.isEnum() && !clazz.isAnonymousClass() && !clazz.isInterface();
    }

    private Collection<File> getAllClassesInPackage(String fromPackage) {
        String path = fromPackage.replace(".", "/");
        URL resource = classLoader.getResource(path);
        if (noMigrationTasks(resource)) {
            return Collections.emptyList();
        }
        return FileUtils.listFiles(new File(resource.getFile()), new String[]{"class"}, true);
    }

    private boolean noMigrationTasks(URL resource) {
        return resource == null;
    }

    private String getClassReference(File classFile) {
        String asPackage = classFile.getPath().replace(File.separator, ".");
        String classes = "classes.";
        return asPackage.substring(asPackage.indexOf(classes) + classes.length());
    }
}