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