
de.is24.deadcode4j.Module 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;
import com.google.common.base.Function;
import com.google.common.base.Optional;
import com.google.common.collect.Ordering;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.io.File;
import java.util.Collection;
import java.util.List;
import static com.google.common.collect.Iterables.addAll;
import static com.google.common.collect.Lists.newArrayList;
import static com.google.common.collect.Lists.newArrayListWithCapacity;
import static de.is24.deadcode4j.Utils.addIfNonNull;
/**
* A Module
represents a java module from the deadcode4j perspective.
*
* @since 2.0.0
*/
public class Module {
@Nonnull
private final String moduleId;
@Nullable
private final String encoding;
@Nonnull
private final Collection dependencies;
@Nullable
private final Repository outputRepository;
@Nonnull
private final List allRepositories;
/**
* Creates a new Module
.
*
* @param moduleId the module's identifier
* @param encoding the module's source encoding
* @param dependencies the resources this module depends on
* @param outputRepository the "output" repository - i.e. the directory where compiled classes can be found
* @param repositories additional repositories to analyze
* @since 2.0.0
*/
public Module(@Nonnull String moduleId,
@Nullable String encoding,
@Nonnull Collection dependencies,
@Nullable Repository outputRepository,
@Nonnull Iterable repositories) {
this.moduleId = moduleId;
this.encoding = encoding;
this.dependencies = dependencies;
this.outputRepository = outputRepository;
this.allRepositories = newArrayList();
addIfNonNull(allRepositories, outputRepository);
addAll(allRepositories, repositories);
}
/**
* Sorts the given modules by their dependencies onto one another, and alphabetically on second order.
*
* @since 2.0.0
*/
@Nonnull
public static Iterable sort(@Nonnull Iterable modules) {
List unsortedModules = newArrayList(modules);
List sortedModules = newArrayListWithCapacity(unsortedModules.size());
while (!unsortedModules.isEmpty()) {
List modulesToAdd = newArrayList();
for (Module module : unsortedModules) {
if (sortedModules.containsAll(module.getRequiredModules())) {
modulesToAdd.add(module);
}
}
if (modulesToAdd.isEmpty()) {
Logger logger = LoggerFactory.getLogger(Module.class);
logger.error("Could not resolve dependencies for all modules! Those modules are affected:");
for (Module unsortedModule : unsortedModules) {
List unresolvedModules = newArrayList(unsortedModule.getRequiredModules());
unresolvedModules.removeAll(sortedModules);
logger.error(" {} requires {}", unsortedModule, unresolvedModules);
}
throw new RuntimeException("Could not build dependency graph!");
}
modulesToAdd = Ordering.natural().onResultOf(toModuleId()).sortedCopy(modulesToAdd);
sortedModules.addAll(modulesToAdd);
unsortedModules.removeAll(modulesToAdd);
}
return sortedModules;
}
@Nonnull
private static Function toModuleId() {
return new Function() {
@Nullable
@Override
public String apply(@Nullable Module input) {
return input == null ? null : input.getModuleId();
}
};
}
@Override
public boolean equals(Object obj) {
return this == obj || Module.class.isInstance(obj) && this.moduleId.equals(Module.class.cast(obj).moduleId);
}
@Override
public int hashCode() {
return this.moduleId.hashCode();
}
@Override
public String toString() {
return "Module [" + this.moduleId + "]";
}
/**
* Returns the module's ID.
*
* @since 2.0.0
*/
@Nonnull
public String getModuleId() {
return moduleId;
}
/**
* Returns the module's source file encoding.
*
* @since 2.0.0
*/
@Nullable
public String getEncoding() {
return encoding;
}
/**
* Returns all class path entries of this module.
*
* @since 2.0.0
*/
@Nonnull
public Iterable getClassPath() {
List classPath = newArrayListWithCapacity(dependencies.size());
for (Resource dependency : dependencies) {
Optional classPathEntry = dependency.getClassPathEntry();
if (classPathEntry.isPresent()) {
classPath.add(classPathEntry.get());
}
}
return classPath;
}
/**
* Returns all modules required by this module, listed in order of their position in the class path.
*
* @since 2.0.0
*/
@Nonnull
public Collection getRequiredModules() {
List requiredModules = newArrayList();
for (Resource dependency : dependencies) {
Optional moduleEntry = dependency.getReferencedModule();
if (moduleEntry.isPresent()) {
requiredModules.add(moduleEntry.get());
}
}
return requiredModules;
}
/**
* Returns the "output" repository - i.e. the directory where compiled classes can be found.
*
* @since 2.0.0
*/
@Nullable
public Repository getOutputRepository() {
return outputRepository;
}
/**
* Returns all repositories to analyze (including the {@link #getOutputRepository() output repository}).
*
* @since 2.0.0
*/
@Nonnull
public Iterable getAllRepositories() {
return this.allRepositories;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy