001/** 002 * 003 * Copyright the original author or authors 004 * 005 * Licensed under the Apache License, Version 2.0 (the "License"); 006 * you may not use this file except in compliance with the License. 007 * 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.jivesoftware.smack.util; 018 019import java.io.BufferedReader; 020import java.io.File; 021import java.io.FileInputStream; 022import java.io.FileNotFoundException; 023import java.io.FileOutputStream; 024import java.io.FileReader; 025import java.io.FileWriter; 026import java.io.IOException; 027import java.io.InputStream; 028import java.io.InputStreamReader; 029import java.io.Reader; 030import java.net.MalformedURLException; 031import java.net.URI; 032import java.net.URL; 033import java.nio.charset.StandardCharsets; 034import java.util.ArrayList; 035import java.util.List; 036import java.util.Set; 037import java.util.logging.Level; 038import java.util.logging.Logger; 039 040public final class FileUtils { 041 042 private static final Logger LOGGER = Logger.getLogger(FileUtils.class.getName()); 043 044 public static InputStream getStreamForClasspathFile(String path, ClassLoader loader) throws IOException { 045 // Get an array of class loaders to try loading the providers files from. 046 List<ClassLoader> classLoaders = getClassLoaders(); 047 if (loader != null) { 048 classLoaders.add(0, loader); 049 } 050 for (ClassLoader classLoader : classLoaders) { 051 InputStream is = classLoader.getResourceAsStream(path); 052 053 if (is != null) { 054 return is; 055 } 056 } 057 throw new IOException("Unable to get '" + path + "' from classpath. Tried ClassLoaders:" + classLoaders); 058 } 059 060 public static InputStream getStreamForUri(URI uri, ClassLoader loader) throws IOException { 061 String protocol = uri.getScheme(); 062 if (protocol.equals("classpath")) { 063 String path = uri.getSchemeSpecificPart(); 064 return getStreamForClasspathFile(path, loader); 065 } 066 067 URL url = uri.toURL(); 068 return url.openStream(); 069 } 070 071 /** 072 * Returns default classloaders. 073 * 074 * @return a List of ClassLoader instances. 075 */ 076 public static List<ClassLoader> getClassLoaders() { 077 ClassLoader[] classLoaders = new ClassLoader[2]; 078 classLoaders[0] = FileUtils.class.getClassLoader(); 079 classLoaders[1] = Thread.currentThread().getContextClassLoader(); 080 081 // Clean up possible null values. Note that #getClassLoader may return a null value. 082 List<ClassLoader> loaders = new ArrayList<ClassLoader>(classLoaders.length); 083 for (ClassLoader classLoader : classLoaders) { 084 if (classLoader != null) { 085 loaders.add(classLoader); 086 } 087 } 088 return loaders; 089 } 090 091 public static boolean addLines(String uriString, Set<String> set) throws MalformedURLException, IOException { 092 URI uri = URI.create(uriString); 093 InputStream is = getStreamForUri(uri, null); 094 InputStreamReader sr = new InputStreamReader(is, StandardCharsets.UTF_8); 095 BufferedReader br = new BufferedReader(sr); 096 try { 097 String line; 098 while ((line = br.readLine()) != null) { 099 set.add(line); 100 } 101 } 102 finally { 103 br.close(); 104 } 105 return true; 106 } 107 108 /** 109 * Reads the contents of a File. 110 * 111 * @param file TODO javadoc me please 112 * @return the content of file or null in case of an error 113 * @throws IOException if an I/O error occurred. 114 */ 115 @SuppressWarnings("DefaultCharset") 116 public static String readFileOrThrow(File file) throws IOException { 117 try (Reader reader = new FileReader(file)) { 118 char[] buf = new char[8192]; 119 int len; 120 StringBuilder s = new StringBuilder(); 121 while ((len = reader.read(buf)) >= 0) { 122 s.append(buf, 0, len); 123 } 124 return s.toString(); 125 } 126 } 127 128 public static String readFile(File file) { 129 try { 130 return readFileOrThrow(file); 131 } catch (FileNotFoundException e) { 132 LOGGER.log(Level.FINE, "readFile", e); 133 } catch (IOException e) { 134 LOGGER.log(Level.WARNING, "readFile", e); 135 } 136 return null; 137 } 138 139 @SuppressWarnings("DefaultCharset") 140 public static void writeFileOrThrow(File file, CharSequence content) throws IOException { 141 FileWriter writer = new FileWriter(file, false); 142 try { 143 writer.write(content.toString()); 144 } finally { 145 writer.close(); 146 } 147 } 148 149 public static boolean writeFile(File file, CharSequence content) { 150 try { 151 writeFileOrThrow(file, content); 152 return true; 153 } 154 catch (IOException e) { 155 LOGGER.log(Level.WARNING, "writeFile", e); 156 return false; 157 } 158 } 159 160 public static FileOutputStream prepareFileOutputStream(File file) throws IOException { 161 if (!file.exists()) { 162 163 // Create parent directory 164 File parent = file.getParentFile(); 165 if (!parent.exists() && !parent.mkdirs()) { 166 throw new IOException("Cannot create directory " + parent.getAbsolutePath()); 167 } 168 169 // Create file 170 if (!file.createNewFile()) { 171 throw new IOException("Cannot create file " + file.getAbsolutePath()); 172 } 173 } 174 175 if (file.isDirectory()) { 176 throw new AssertionError("File " + file.getAbsolutePath() + " is not a file!"); 177 } 178 179 return new FileOutputStream(file); 180 } 181 182 public static FileInputStream prepareFileInputStream(File file) throws IOException { 183 if (file.exists()) { 184 if (file.isFile()) { 185 return new FileInputStream(file); 186 } else { 187 throw new IOException("File " + file.getAbsolutePath() + " is not a file!"); 188 } 189 } else { 190 throw new FileNotFoundException("File " + file.getAbsolutePath() + " not found."); 191 } 192 } 193 194 public static void maybeDeleteFileOrThrow(File file) throws IOException { 195 if (!file.exists()) { 196 return; 197 } 198 199 boolean successfullyDeleted = file.delete(); 200 if (!successfullyDeleted) { 201 throw new IOException("Could not delete file " + file); 202 } 203 } 204 205 public static void maybeCreateFileWithParentDirectories(File file) throws IOException { 206 File parent = file.getParentFile(); 207 if (!parent.exists() && !parent.mkdirs()) { 208 throw new IOException("Cannot create directory " + parent); 209 } 210 211 if (file.isFile()) { 212 return; 213 } 214 215 if (!file.exists()) { 216 if (file.createNewFile()) { 217 return; 218 } 219 throw new IOException("Cannot create file " + file); 220 } 221 222 if (file.isDirectory()) { 223 throw new IOException("File " + file + " exists, but is a directory."); 224 } else { 225 throw new IOException("File " + file + " exists, but is neither a file nor a directory"); 226 } 227 } 228}