All Downloads are FREE. Search and download functionalities are using the official Maven repository.

de.is24.deadcode4j.analyzer.InterfacesAnalyzer Maven / Gradle / Ivy

There is a newer version: 2.1.0
Show newest version
package de.is24.deadcode4j.analyzer;

import de.is24.deadcode4j.AnalysisContext;
import de.is24.deadcode4j.analyzer.javassist.ClassPathFilter;
import de.is24.guava.NonNullFunction;
import javassist.CtClass;

import javax.annotation.Nonnull;
import java.util.Set;

import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.collect.Sets.newHashSet;
import static de.is24.javassist.CtClasses.getAllImplementedInterfaces;
import static java.util.Collections.disjoint;

/**
 * Serves as a base class with which to mark classes as being in use if they explicitly implement one of the specified
 * interfaces.
 *
 * @since 1.4
 */
public abstract class InterfacesAnalyzer extends ByteCodeAnalyzer {

    @Nonnull
    private final String dependerId;
    private final NonNullFunction> supplyInterfacesFoundInClassPath;

    private InterfacesAnalyzer(@Nonnull String dependerId, @Nonnull Set interfaceNames) {
        checkArgument(!interfaceNames.isEmpty(), "interfaceNames cannot by empty!");
        this.dependerId = dependerId;
        this.supplyInterfacesFoundInClassPath = new ClassPathFilter(interfaceNames);
    }

    /**
     * Creates a new InterfacesAnalyzer.
     *
     * @param dependerId     a description of the depending entity with which to
     *                       call {@link de.is24.deadcode4j.AnalysisContext#addDependencies(String, Iterable)}
     * @param interfaceNames a list of fully qualified interface names indicating that the implementing class is still
     *                       in use
     * @since 1.4
     */
    protected InterfacesAnalyzer(@Nonnull String dependerId, @Nonnull String... interfaceNames) {
        this(dependerId, newHashSet(interfaceNames));
    }

    /**
     * Creates a new InterfacesAnalyzer.
     *
     * @param dependerId     a description of the depending entity with which to
     *                       call {@link de.is24.deadcode4j.AnalysisContext#addDependencies(String, Iterable)}
     * @param interfaceNames a list of fully qualified interface names indicating that the implementing class is still
     *                       in use
     * @since 1.4
     */
    protected InterfacesAnalyzer(@Nonnull String dependerId, @Nonnull Iterable interfaceNames) {
        this(dependerId, newHashSet(interfaceNames));
    }

    @Override
    protected final void analyzeClass(@Nonnull AnalysisContext analysisContext, @Nonnull CtClass clazz) {
        Set knownInterfaces = getInterfacesFoundInClassPath(analysisContext);
        if (knownInterfaces.isEmpty()) {
            return;
        }

        String clazzName = clazz.getName();
        analysisContext.addAnalyzedClass(clazzName);
        if (!disjoint(knownInterfaces, getAllImplementedInterfaces(clazz))) {
            analysisContext.addDependencies(this.dependerId, clazzName);
        }
    }

    @Nonnull
    protected final Set getInterfacesFoundInClassPath(@Nonnull AnalysisContext analysisContext) {
        return analysisContext.getOrCreateCacheEntry(getClass(), supplyInterfacesFoundInClassPath);
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy