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

org.pitest.mutationtest.tooling.DirectorySourceLocator Maven / Gradle / Ivy

There is a newer version: 1.17.1
Show newest version
/*
 * Copyright 2010 Henry Coles
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and limitations under the License.
 */
package org.pitest.mutationtest.tooling;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Collection;
import java.util.Optional;
import java.util.stream.Stream;

import org.pitest.classinfo.ClassName;
import org.pitest.mutationtest.SourceLocator;
import org.pitest.util.Unchecked;

public class DirectorySourceLocator implements SourceLocator {

    private final Path root;
    private final Charset inputCharset;

    public DirectorySourceLocator(Path root, Charset inputCharset) {
        this.root = root;
        this.inputCharset = inputCharset;
    }

    @Override
    public Optional locate(Collection classes, String fileName) {

        if (!Files.exists(root)) {
            return Optional.empty();
        }

        // look for matching filename in directories matching its package.
        Optional path = classes.stream()
                .map(ClassName::fromString)
                .map(ClassName::getPackage)
                .distinct()
                .map(c -> toFileName(c, fileName))
                .map(file -> root.resolve(file))
                .filter(Files::exists)
                .filter(Files::isRegularFile)
                .findFirst();

        // If there is no file in the expected location (kotlin file?), search from the root, but
        // in this case we cannot know if we have the right file if the same name occurs more than once in the file tree
        // (cannot do this as an or as only introduced in java 9)
        if (path.isPresent()) {
            return path
                    .map(this::toReader);
        } else {
            return searchFromRoot(fileName)
                    .map(this::toReader);
        }
    }

    @Override
    // String value of path is used to select order to check
    // roots when locating files across multiple modules
    public String toString() {
        return root.toString();
    }

    private String toFileName(ClassName packge, String fileName) {
        if (packge.asJavaName().equals("")) {
            return fileName;
        }
        return packge.asJavaName().replace(".", File.separator) + File.separator + fileName;
    }

    private Reader toReader(Path path) {
        try {
            return new InputStreamReader(new BufferedInputStream(Files.newInputStream(path)),
                    inputCharset);
        } catch (IOException e) {
            throw Unchecked.translateCheckedException(e);
        }
    }

    private Optional searchFromRoot(String fileName) {
        try {
            try (Stream matches = Files.find(root, 100,
                            (path, attributes) -> path.getFileName().toString().equals(fileName) && attributes.isRegularFile())) {
                return matches.findFirst();
            }

        } catch (IOException e) {
            throw Unchecked.translateCheckedException(e);
        }
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy