001// SPDX-FileCopyrightText: 2021 Paul Schaub <vanitasvitae@fsfe.org> 002// 003// SPDX-License-Identifier: Apache-2.0 004 005package sop.cli.picocli; 006 007import java.io.File; 008import java.io.FileInputStream; 009import java.io.FileNotFoundException; 010import java.io.IOException; 011 012import sop.exception.SOPGPException; 013 014public class FileUtil { 015 016 private static final String ERROR_AMBIGUOUS = "File name '%s' is ambiguous. File with the same name exists on the filesystem."; 017 private static final String ERROR_ENV_FOUND = "Environment variable '%s' not set."; 018 private static final String ERROR_OUTPUT_EXISTS = "Output file '%s' already exists."; 019 private static final String ERROR_INPUT_NOT_EXIST = "File '%s' does not exist."; 020 private static final String ERROR_CANNOT_CREATE_FILE = "Output file '%s' cannot be created: %s"; 021 022 public static final String PRFX_ENV = "@ENV:"; 023 public static final String PRFX_FD = "@FD:"; 024 025 private static EnvironmentVariableResolver envResolver = System::getenv; 026 027 public static void setEnvironmentVariableResolver(EnvironmentVariableResolver envResolver) { 028 if (envResolver == null) { 029 throw new NullPointerException("Variable envResolver cannot be null."); 030 } 031 FileUtil.envResolver = envResolver; 032 } 033 034 public interface EnvironmentVariableResolver { 035 /** 036 * Resolve the value of the given environment variable. 037 * Return null if the variable is not present. 038 * 039 * @param name name of the variable 040 * @return variable value or null 041 */ 042 String resolveEnvironmentVariable(String name); 043 } 044 045 public static File getFile(String fileName) { 046 if (fileName == null) { 047 throw new NullPointerException("File name cannot be null."); 048 } 049 050 if (fileName.startsWith(PRFX_ENV)) { 051 052 if (new File(fileName).exists()) { 053 throw new SOPGPException.AmbiguousInput(String.format(ERROR_AMBIGUOUS, fileName)); 054 } 055 056 String envName = fileName.substring(PRFX_ENV.length()); 057 String envValue = envResolver.resolveEnvironmentVariable(envName); 058 if (envValue == null) { 059 throw new IllegalArgumentException(String.format(ERROR_ENV_FOUND, envName)); 060 } 061 return new File(envValue); 062 } else if (fileName.startsWith(PRFX_FD)) { 063 064 if (new File(fileName).exists()) { 065 throw new SOPGPException.AmbiguousInput(String.format(ERROR_AMBIGUOUS, fileName)); 066 } 067 068 throw new IllegalArgumentException("File descriptors not supported."); 069 } 070 071 return new File(fileName); 072 } 073 074 public static FileInputStream getFileInputStream(String fileName) { 075 File file = getFile(fileName); 076 try { 077 FileInputStream inputStream = new FileInputStream(file); 078 return inputStream; 079 } catch (FileNotFoundException e) { 080 throw new SOPGPException.MissingInput(String.format(ERROR_INPUT_NOT_EXIST, fileName), e); 081 } 082 } 083 084 public static File createNewFileOrThrow(File file) throws IOException { 085 if (file == null) { 086 throw new NullPointerException("File cannot be null."); 087 } 088 089 try { 090 if (!file.createNewFile()) { 091 throw new SOPGPException.OutputExists(String.format(ERROR_OUTPUT_EXISTS, file.getAbsolutePath())); 092 } 093 } catch (IOException e) { 094 throw new IOException(String.format(ERROR_CANNOT_CREATE_FILE, file.getAbsolutePath(), e.getMessage())); 095 } 096 return file; 097 } 098}