001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache license, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the license for the specific language governing permissions and 015 * limitations under the license. 016 */ 017package org.apache.logging.log4j.core.util; 018 019import java.io.File; 020import java.io.IOException; 021import java.io.UnsupportedEncodingException; 022import java.net.MalformedURLException; 023import java.net.URI; 024import java.net.URL; 025import java.net.URLDecoder; 026import java.nio.charset.StandardCharsets; 027import java.nio.file.FileSystem; 028import java.nio.file.FileSystems; 029import java.nio.file.Path; 030 031import org.apache.logging.log4j.Logger; 032import org.apache.logging.log4j.status.StatusLogger; 033 034/** 035 * File utilities. 036 */ 037public final class FileUtils { 038 039 /** Constant for the file URL protocol. */ 040 private static final String PROTOCOL_FILE = "file"; 041 042 private static final String JBOSS_FILE = "vfsfile"; 043 044 private static final Logger LOGGER = StatusLogger.getLogger(); 045 046 private FileUtils() { 047 } 048 049 /** 050 * Tries to convert the specified URI to a file object. If this fails, <b>null</b> is returned. 051 * 052 * @param uri the URI 053 * @return the resulting file object 054 */ 055 public static File fileFromUri(URI uri) { 056 // There MUST be a better way to do this. TODO Search other ASL projects... 057 if (uri == null 058 || (uri.getScheme() != null && (!PROTOCOL_FILE.equals(uri.getScheme()) && !JBOSS_FILE.equals(uri 059 .getScheme())))) { 060 return null; 061 } 062 if (uri.getScheme() == null) { 063 File file = new File(uri.toString()); 064 if (file.exists()) { 065 return file; 066 } 067 try { 068 final String path = uri.getPath(); 069 file = new File(path); 070 if (file.exists()) { 071 return file; 072 } 073 uri = new File(path).toURI(); 074 } catch (final Exception ex) { 075 LOGGER.warn("Invalid URI {}", uri); 076 return null; 077 } 078 } 079 final String charsetName = StandardCharsets.UTF_8.name(); 080 try { 081 String fileName = uri.toURL().getFile(); 082 if (new File(fileName).exists()) { // LOG4J2-466 083 return new File(fileName); // allow files with '+' char in name 084 } 085 fileName = URLDecoder.decode(fileName, charsetName); 086 return new File(fileName); 087 } catch (final MalformedURLException ex) { 088 LOGGER.warn("Invalid URL {}", uri, ex); 089 } catch (final UnsupportedEncodingException uee) { 090 LOGGER.warn("Invalid encoding: {}", charsetName, uee); 091 } 092 return null; 093 } 094 095 public static boolean isFile(final URL url) { 096 return url != null && (url.getProtocol().equals(PROTOCOL_FILE) || url.getProtocol().equals(JBOSS_FILE)); 097 } 098 099 public static String getFileExtension(File file) { 100 String fileName = file.getName(); 101 if (fileName.lastIndexOf(".") != -1 && fileName.lastIndexOf(".") != 0) { 102 return fileName.substring(fileName.lastIndexOf(".") + 1); 103 } else { 104 return null; 105 } 106 } 107 108 /** 109 * Asserts that the given directory exists and creates it if necessary. 110 * 111 * @param dir the directory that shall exist 112 * @param createDirectoryIfNotExisting specifies if the directory shall be created if it does not exist. 113 * @throws java.io.IOException thrown if the directory could not be created. 114 */ 115 public static void mkdir(final File dir, final boolean createDirectoryIfNotExisting) throws IOException { 116 // commons io FileUtils.forceMkdir would be useful here, we just want to omit this dependency 117 if (!dir.exists()) { 118 if (!createDirectoryIfNotExisting) { 119 throw new IOException("The directory " + dir.getAbsolutePath() + " does not exist."); 120 } 121 if (!dir.mkdirs()) { 122 throw new IOException("Could not create directory " + dir.getAbsolutePath()); 123 } 124 } 125 if (!dir.isDirectory()) { 126 throw new IOException("File " + dir + " exists and is not a directory. Unable to create directory."); 127 } 128 } 129}