PathUtil.java

/*
 * Copyright (c) 2017, Stein Eldar Johnsen
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you 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 net.morimekta.file;

import java.nio.file.Path;
import java.util.Optional;

import static java.util.Objects.requireNonNull;

/**
 * Utility for helping with file names and paths.
 */
public final class PathUtil {
    /**
     * Get the base name of a file. The base name is the file name without a file suffix.
     * This means finding the last '.' and strip away all after that, but only it is a
     * lone '.'. If the filename is e.g. 'test..file', that whole becomes the name. Also
     * a leading ".." or "." will not count as a file suffix. This means the file
     * suffix (see {@link #getFileSuffix(Path)}) may not contain a '.'.
     *
     * @param path The file path.
     * @return The file name without suffix.
     */
    public static String getFileBaseName(Path path) {
        return getFileBaseName(getFileName(path));
    }

    /**
     * Get the base name of a file. The base name is the file name without a file suffix.
     * This means finding the last '.' and strip away all after that, but only it is a
     * lone '.'. If the filename is e.g. 'test..file', that whole becomes the name. Also
     * a leading ".." or "." will not count as a file suffix. This means the file
     * suffix (see {@link #getFileSuffix(Path)}) may not contain a '.'.
     *
     * @param fileName The file name. If the file name contains '/' (path separator),
     *                 the result of this function is undefined.
     * @return The file name without suffix.
     */
    public static String getFileBaseName(String fileName) {
        requireNonNull(fileName, "fileName == null");
        int dot = fileName.lastIndexOf('.');
        if (dot > 0 && fileName.charAt(dot - 1) == '.') {
            return fileName;
        }
        if (dot > 0) {
            return fileName.substring(0, dot);
        }
        return fileName;
    }

    /**
     * Get file suffix. The file suffix is all that is not considered the file name.
     * The file suffix may not contain '.', and it must be separated from a non-empty
     * file base name with a single '.'.
     *
     * @param path The file path.
     * @return The suffix.
     */
    public static String getFileSuffix(Path path) {
        return getFileSuffix(getFileName(path));
    }

    /**
     * Get file suffix. The file suffix is all that is not considered the file name.
     * The file suffix may not contain '.', and it must be separated from a non-empty
     * file base name with a single '.'.
     *
     * @param fileName The file name. If the file name contains '/' (path separator),
     *                 the result of this function is undefined.
     * @return The suffix.
     */
    public static String getFileSuffix(String fileName) {
        requireNonNull(fileName, "fileName == null");
        int dot = fileName.lastIndexOf('.');
        if (dot > 0 && fileName.charAt(dot - 1) == '.') {
            return "";
        }
        if (dot > 0) {
            return fileName.substring(dot + 1);
        }
        return "";
    }

    /**
     * Get file name.
     *
     * @param path The file path.
     * @return The full filename.
     */
    public static String getFileName(Path path) {
        requireNonNull(path, "path == null");
        return Optional.ofNullable(path.getFileName())
                       .map(Path::toString)
                       .orElse("");
    }

    private PathUtil() {}
}