
de.is24.deadcode4j.analyzer.SpringDataCustomRepositoriesAnalyzer Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of deadcode4j-maven-plugin Show documentation
Show all versions of deadcode4j-maven-plugin Show documentation
Finds unused classes of a project
package de.is24.deadcode4j.analyzer;
import de.is24.deadcode4j.AnalysisContext;
import javassist.CtClass;
import javassist.Modifier;
import javax.annotation.Nonnull;
import java.util.List;
import java.util.Set;
import static com.google.common.collect.Lists.newArrayList;
import static de.is24.deadcode4j.IntermediateResults.*;
import static de.is24.javassist.CtClasses.getAllImplementedInterfaces;
/**
* Analyzes class files: marks custom implementations of Spring Data repositories as being in use.
* Note that this analyzer only considers the default naming convention RepositoryNameImpl
to
* identify custom implementations.
*
* @since 2.0.0
*/
public class SpringDataCustomRepositoriesAnalyzer extends ByteCodeAnalyzer {
private List customRepositoryNames = newArrayList();
@Override
protected void analyzeClass(@Nonnull AnalysisContext analysisContext, @Nonnull CtClass clazz) {
analysisContext.addAnalyzedClass(clazz.getName());
if (clazz.isInterface()) {
analyzeInterface(analysisContext, clazz);
} else if (isPublicOrPackageProtectedClass(clazz)) {
reportImplementationOfExistingCustomRepository(analysisContext, clazz);
}
}
@Override
public void finishAnalysis(@Nonnull AnalysisContext analysisContext) {
analysisContext.getCache().put(getClass(), resultSetFor(this.customRepositoryNames));
this.customRepositoryNames.clear();
}
private void analyzeInterface(@Nonnull AnalysisContext analysisContext, @Nonnull CtClass clazz) {
Set implementedInterfaces = getAllImplementedInterfaces(clazz);
if (!implementedInterfaces.contains("org.springframework.data.repository.Repository")) {
return;
}
final String nameOfCustomRepositoryInterface = clazz.getName() + "Custom";
if (!implementedInterfaces.contains(nameOfCustomRepositoryInterface)) {
return;
}
this.customRepositoryNames.add(nameOfCustomRepositoryInterface);
reportImplementationOfNewCustomRepository(analysisContext, clazz);
}
private void reportImplementationOfNewCustomRepository(@Nonnull AnalysisContext analysisContext,
@Nonnull CtClass clazz) {
final String clazzName = clazz.getName();
final String nameOfCustomRepositoryImplementation = clazzName + "Impl";
CtClass customImpl = clazz.getClassPool().getOrNull(nameOfCustomRepositoryImplementation);
if (customImpl == null) {
return;
}
Set implementedInterfaces = getAllImplementedInterfaces(customImpl);
if (implementedInterfaces.contains(clazzName + "Custom")) {
analysisContext.addDependencies(clazzName, nameOfCustomRepositoryImplementation);
}
}
private boolean isPublicOrPackageProtectedClass(@Nonnull CtClass clazz) {
int modifiers = clazz.getModifiers();
return !Modifier.isAbstract(modifiers)
&& !Modifier.isAnnotation(modifiers)
&& !Modifier.isEnum(modifiers)
&& !Modifier.isPrivate(modifiers)
&& !Modifier.isProtected(modifiers);
}
private void reportImplementationOfExistingCustomRepository(@Nonnull AnalysisContext analysisContext,
@Nonnull CtClass clazz) {
IntermediateResultSet intermediateResults = resultSetFrom(analysisContext, getClass());
if (intermediateResults == null) {
return;
}
Set existingCustomRepositories = intermediateResults.getResults();
Set implementedInterfaces = getAllImplementedInterfaces(clazz);
implementedInterfaces.retainAll(existingCustomRepositories);
for (String customRepositoryName : implementedInterfaces) {
analysisContext.addDependencies(
customRepositoryName.substring(0, customRepositoryName.length() - "Custom".length()),
clazz.getName());
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy