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

de.is24.deadcode4j.Module Maven / Gradle / Ivy

There is a newer version: 2.1.0
Show newest version
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