UnusedLocalFileDetector.java
/**
* Copyright (c) 2018 European Organisation for Nuclear Research (CERN), All Rights Reserved.
*/
package cern.accsoft.steering.jmad.tools.modeldefs.cleaning;
import static cern.accsoft.steering.jmad.modeldefs.io.impl.ModelDefinitionUtil.getRequiredModelFiles;
import static cern.accsoft.steering.jmad.modeldefs.io.impl.ModelDefinitionUtil.nonIgnoredFilesBelow;
import static com.google.common.collect.Sets.difference;
import static java.util.Objects.requireNonNull;
import static java.util.stream.Collectors.toSet;
import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.util.HashSet;
import java.util.Optional;
import java.util.Set;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets.SetView;
import cern.accsoft.steering.jmad.modeldefs.domain.JMadModelDefinition;
import cern.accsoft.steering.jmad.modeldefs.io.JMadModelDefinitionImporter;
import cern.accsoft.steering.jmad.modeldefs.io.ModelFileFinder;
import cern.accsoft.steering.jmad.modeldefs.io.ModelFileFinderManager;
import cern.accsoft.steering.jmad.modeldefs.io.impl.ModelDefinitionUtil;
public class UnusedLocalFileDetector {
private static final Logger LOGGER = LoggerFactory.getLogger(UnusedLocalFileDetector.class);
private final JMadModelDefinitionImporter modelDefinitionImporter;
private final ModelFileFinderManager fileFinderManager;
public UnusedLocalFileDetector(JMadModelDefinitionImporter modelDefinitionImporter,
ModelFileFinderManager fileFinderManager) {
this.modelDefinitionImporter = requireNonNull(modelDefinitionImporter,
"modelDefinitionImporter must not be null");
this.fileFinderManager = requireNonNull(fileFinderManager, "fileFinderManager must not be null");
}
public Set<File> detectUnusedFiles(Path rootPath) {
Set<File> modelDefinitionFiles = ModelDefinitionUtil.modelDefinitionFilesBelow(rootPath);
LOGGER.info("Found model definition files below {} :\n{}", rootPath, modelDefinitionFiles);
Set<JMadModelDefinition> modelDefs = modelDefinitionFiles.stream()
.flatMap(f -> modelDefinitionImporter.importModelDefinitions(f).stream()).collect(toSet());
Set<File> requiredLocalFiles = new HashSet<>();
requiredLocalFiles
.addAll(modelDefinitionFiles.stream().map(UnusedLocalFileDetector::canonicalFile).collect(toSet()));
for (JMadModelDefinition md : modelDefs) {
ModelFileFinder finder = fileFinderManager.getModelFileFinder(md);
Set<Optional<File>> localFiles = getRequiredModelFiles(md).stream().map(finder::getLocalSourceFile)
.collect(toSet());
if (!localFiles.stream().allMatch(Optional::isPresent)) {
throw new IllegalStateException(
"Not all Files of model definition '" + md + "' are local files! Cannot proceed.");
}
Set<File> absoluteFiles = localFiles.stream().map(Optional::get).map(UnusedLocalFileDetector::canonicalFile)
.collect(toSet());
LOGGER.info("Model definition {} uses the following files: {}", md, absoluteFiles);
requiredLocalFiles.addAll(absoluteFiles);
}
Set<File> allFiles = nonIgnoredFilesBelow(rootPath).stream().map(UnusedLocalFileDetector::canonicalFile)
.collect(toSet());
SetView<File> difference = difference(allFiles, requiredLocalFiles);
return ImmutableSet.copyOf(difference);
}
private static File canonicalFile(File file) {
try {
return file.getCanonicalFile();
} catch (IOException e) {
throw new IllegalArgumentException("Canonical file of file '" + file + "' cannot be determined.");
}
}
}