package ch.ge.ve.commons.fileutils;
/*-
* #%L
* Common file utilities
* %%
* Copyright (C) 2015 - 2016 République et Canton de Genève
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Optional;
import java.util.regex.Pattern;
import java.util.stream.Stream;
import java.time.format.DateTimeFormatter;
import java.time.ZonedDateTime;
/**
* Utility class to manage the parametrized output file names.
* <p/>
* The supported parameters are the following and are replaced at runtime with the given values:
* <ul>
* <li>{date}: the date of the file generation in 'yyyyMMdd' format</li>
* <li>{datetime}: date and time of the file generation in 'yyyy-MM-dd-HH'h'mm'm'ss's'' format</li>
* <li>{user}: the user of the application: the windows account name</li>
* <li>{operationCode}: the code of the operation for which the file is generated</li>
* <li>{canton}: the canton of the operation for which the file is generated</li>
* </ul>
*/
public class OutputFilesPattern {
public static final String DATE_TIME_FORMAT = "yyyy-MM-dd-HH'h'mm'm'ss's'";
public static final String DATE_FORMAT = "yyyyMMdd";
private static final int FIND_FILES_MAX_DEPTH = 10;
private final DateTimeFormatter datetimeFormat = DateTimeFormatter.ofPattern(DATE_TIME_FORMAT);
private final DateTimeFormatter dateFormat = DateTimeFormatter.ofPattern(DATE_FORMAT);
/**
* Resolves the parameters {date}, {datetime} and {user}
*
* @param pattern
* @param user
* @param date
* @return
*/
public String injectParams(String pattern, String user, ZonedDateTime date) {
String result = pattern.replace("{date}", getDateAsString(date));
result = result.replace("{datetime}", getDateTimeAsString(date));
result = result.replace("{user}", user);
return result;
}
/**
* Resolves the parameters {date}, {datetime} and {user}.</br>
* user is resolved from environment variable 'user.name'
*
* @param pattern parametrized file name
* @param date the date and time of the file generation
* @return the final file name
*/
public String injectParams(String pattern, ZonedDateTime date) {
return injectParams(pattern, getSystemUserName(), date);
}
/**
* Resolves the parameters {date}, {datetime}, {user} and {operationCode}
*
* @param pattern parametrized file name
* @param user user
* @param date the date and time of the file generation
* @param operationCode the code of the operation
* @return the final file name
*/
public String injectParams(String pattern, String user, ZonedDateTime date, String operationCode) {
String result = injectParams(pattern, user, date);
result = result.replace("{operationCode}", operationCode);
return result;
}
/**
* Resolves the parameters {date}, {datetime}, {user} and {operationCode}
*
* @param pattern parametrized file name
* @param date the date and time of the file generation
* @param operationCode the code of the operation
* @return the final file name
*/
public String injectParams(String pattern, ZonedDateTime date, String operationCode) {
return injectParams(pattern, getSystemUserName(), date, operationCode);
}
/**
* Resolves all the parameters.
*
* @param pattern parametrized file name
* @param user user
* @param date the date and time of the file generation
* @param operationCode the code of the operation
* @param hostingCode the canton of the operation
* @return the final file name
*/
public String injectParams(String pattern, String user, ZonedDateTime date, String operationCode, String hostingCode) {
String result = injectParams(pattern, user, date, operationCode);
result = result.replace("{canton}", hostingCode);
return result;
}
/**
* Resolves all the parameters.
*
* @param pattern parametrized file name
* @param user user
* @param date the date and time of the file generation
* @param operationCode the code of the operation
* @param hostingCode the canton of the operation
* @param votersName the name of the voters group
* @return the final file name
*/
public String injectParams(String pattern, String user, ZonedDateTime date, String operationCode, String hostingCode, String votersName) {
String result = injectParams(pattern, user, date, operationCode, hostingCode);
result = result.replace("{votersName}", votersName);
return result;
}
/**
* Resolves all the parameters.
*
* @param pattern parametrized file name
* @param date the date and time of the file generation
* @param operationCode the code of the operation
* @param hostingCode the canton of the operation
* @return the final file name
*/
public String injectParams(String pattern, ZonedDateTime date, String operationCode, String hostingCode) {
return injectParams(pattern, getSystemUserName(), date, operationCode, hostingCode);
}
/**
* Resolves all the parameters.
*
* @param pattern parametrized file name
* @param date the date and time of the file generation
* @param operationCode the code of the operation
* @param hostingCode the canton of the operation
* @param votersName the name of the voters group
* @return the final file name
*/
public String injectParams(String pattern, ZonedDateTime date, String operationCode, String hostingCode, String votersName) {
return injectParams(pattern, getSystemUserName(), date, operationCode, hostingCode, votersName);
}
/**
* Tries to find a file matching a given <i>filenamePattern</i> regular expression.
*
* @param filenamePattern regular expression pattern that the file should match
* @param rootPath path from which to recursively search for the file
* @return the first file matching the pattern from the root directory, or an empty optional if none matched
*/
public Optional<Path> findFirstFileByPattern(final Pattern filenamePattern, Path rootPath) {
try (Stream<Path> pathStream = Files.find(
rootPath,
FIND_FILES_MAX_DEPTH,
(path, attr) -> filenamePattern.matcher(path.getFileName().toString()).matches())) {
return pathStream.sorted().findFirst();
} catch (IOException e) {
throw new FileOperationRuntimeException("Cannot walk file tree", e);
}
}
private String getDateAsString(ZonedDateTime date) {
return dateFormat.format(date);
}
private String getDateTimeAsString(ZonedDateTime date) {
return datetimeFormat.format(date);
}
private static String getSystemUserName() {
return System.getProperty("user.name");
}
}