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 */ 017 package org.apache.activemq.util; 018 019 import java.io.File; 020 import java.io.FileInputStream; 021 import java.io.FileNotFoundException; 022 import java.io.FileOutputStream; 023 import java.io.FilenameFilter; 024 import java.io.IOException; 025 import java.io.InputStream; 026 import java.io.OutputStream; 027 import java.util.ArrayList; 028 import java.util.List; 029 030 /** 031 * 032 */ 033 public final class IOHelper { 034 protected static final int MAX_DIR_NAME_LENGTH; 035 protected static final int MAX_FILE_NAME_LENGTH; 036 private static final int DEFAULT_BUFFER_SIZE = 4096; 037 private IOHelper() { 038 } 039 040 public static String getDefaultDataDirectory() { 041 return getDefaultDirectoryPrefix() + "activemq-data"; 042 } 043 044 public static String getDefaultStoreDirectory() { 045 return getDefaultDirectoryPrefix() + "amqstore"; 046 } 047 048 /** 049 * Allows a system property to be used to overload the default data 050 * directory which can be useful for forcing the test cases to use a target/ 051 * prefix 052 */ 053 public static String getDefaultDirectoryPrefix() { 054 try { 055 return System.getProperty("org.apache.activemq.default.directory.prefix", ""); 056 } catch (Exception e) { 057 return ""; 058 } 059 } 060 061 /** 062 * Converts any string into a string that is safe to use as a file name. 063 * The result will only include ascii characters and numbers, and the "-","_", and "." characters. 064 * 065 * @param name 066 * @return 067 */ 068 public static String toFileSystemDirectorySafeName(String name) { 069 return toFileSystemSafeName(name, true, MAX_DIR_NAME_LENGTH); 070 } 071 072 public static String toFileSystemSafeName(String name) { 073 return toFileSystemSafeName(name, false, MAX_FILE_NAME_LENGTH); 074 } 075 076 /** 077 * Converts any string into a string that is safe to use as a file name. 078 * The result will only include ascii characters and numbers, and the "-","_", and "." characters. 079 * 080 * @param name 081 * @param dirSeparators 082 * @param maxFileLength 083 * @return 084 */ 085 public static String toFileSystemSafeName(String name,boolean dirSeparators,int maxFileLength) { 086 int size = name.length(); 087 StringBuffer rc = new StringBuffer(size * 2); 088 for (int i = 0; i < size; i++) { 089 char c = name.charAt(i); 090 boolean valid = c >= 'a' && c <= 'z'; 091 valid = valid || (c >= 'A' && c <= 'Z'); 092 valid = valid || (c >= '0' && c <= '9'); 093 valid = valid || (c == '_') || (c == '-') || (c == '.') || (c=='#') 094 ||(dirSeparators && ( (c == '/') || (c == '\\'))); 095 096 if (valid) { 097 rc.append(c); 098 } else { 099 // Encode the character using hex notation 100 rc.append('#'); 101 rc.append(HexSupport.toHexFromInt(c, true)); 102 } 103 } 104 String result = rc.toString(); 105 if (result.length() > maxFileLength) { 106 result = result.substring(result.length()-maxFileLength,result.length()); 107 } 108 return result; 109 } 110 111 public static boolean deleteFile(File fileToDelete) { 112 if (fileToDelete == null || !fileToDelete.exists()) { 113 return true; 114 } 115 boolean result = deleteChildren(fileToDelete); 116 result &= fileToDelete.delete(); 117 return result; 118 } 119 120 public static boolean deleteChildren(File parent) { 121 if (parent == null || !parent.exists()) { 122 return false; 123 } 124 boolean result = true; 125 if (parent.isDirectory()) { 126 File[] files = parent.listFiles(); 127 if (files == null) { 128 result = false; 129 } else { 130 for (int i = 0; i < files.length; i++) { 131 File file = files[i]; 132 if (file.getName().equals(".") 133 || file.getName().equals("..")) { 134 continue; 135 } 136 if (file.isDirectory()) { 137 result &= deleteFile(file); 138 } else { 139 result &= file.delete(); 140 } 141 } 142 } 143 } 144 145 return result; 146 } 147 148 149 public static void moveFile(File src, File targetDirectory) throws IOException { 150 if (!src.renameTo(new File(targetDirectory, src.getName()))) { 151 throw new IOException("Failed to move " + src + " to " + targetDirectory); 152 } 153 } 154 155 public static void copyFile(File src, File dest) throws IOException { 156 copyFile(src,dest,null); 157 } 158 159 public static void copyFile(File src, File dest, FilenameFilter filter) throws IOException { 160 if (src.getCanonicalPath().equals(dest.getCanonicalPath()) == false) { 161 if (src.isDirectory()) { 162 163 mkdirs(dest); 164 List<File> list = getFiles(src, filter); 165 for (File f : list) { 166 if (f.isFile()) { 167 File target = new File(getCopyParent(src, dest, f), f.getName()); 168 copySingleFile(f, target); 169 } 170 } 171 172 } else if (dest.isDirectory()) { 173 mkdirs(dest); 174 File target = new File(dest, src.getName()); 175 copySingleFile(src, target); 176 } else { 177 copySingleFile(src, dest); 178 } 179 } 180 } 181 182 static File getCopyParent(File from, File to, File src) { 183 File result = null; 184 File parent = src.getParentFile(); 185 String fromPath = from.getAbsolutePath(); 186 if (parent.getAbsolutePath().equals(fromPath)) { 187 //one level down 188 result = to; 189 }else { 190 String parentPath = parent.getAbsolutePath(); 191 String path = parentPath.substring(fromPath.length()); 192 result = new File(to.getAbsolutePath()+File.separator+path); 193 } 194 return result; 195 } 196 197 static List<File> getFiles(File dir,FilenameFilter filter){ 198 List<File> result = new ArrayList<File>(); 199 getFiles(dir,result,filter); 200 return result; 201 } 202 203 static void getFiles(File dir,List<File> list,FilenameFilter filter) { 204 if (!list.contains(dir)) { 205 list.add(dir); 206 String[] fileNames=dir.list(filter); 207 for (int i =0; i < fileNames.length;i++) { 208 File f = new File(dir,fileNames[i]); 209 if (f.isFile()) { 210 list.add(f); 211 }else { 212 getFiles(dir,list,filter); 213 } 214 } 215 } 216 } 217 218 219 public static void copySingleFile(File src, File dest) throws IOException { 220 FileInputStream fileSrc = new FileInputStream(src); 221 FileOutputStream fileDest = new FileOutputStream(dest); 222 copyInputStream(fileSrc, fileDest); 223 } 224 225 public static void copyInputStream(InputStream in, OutputStream out) throws IOException { 226 byte[] buffer = new byte[DEFAULT_BUFFER_SIZE]; 227 int len = in.read(buffer); 228 while (len >= 0) { 229 out.write(buffer, 0, len); 230 len = in.read(buffer); 231 } 232 in.close(); 233 out.close(); 234 } 235 236 static { 237 MAX_DIR_NAME_LENGTH = Integer.valueOf(System.getProperty("MaximumDirNameLength","200")).intValue(); 238 MAX_FILE_NAME_LENGTH = Integer.valueOf(System.getProperty("MaximumFileNameLength","64")).intValue(); 239 } 240 241 242 public static void mkdirs(File dir) throws IOException { 243 if (dir.exists()) { 244 if (!dir.isDirectory()) { 245 throw new IOException("Failed to create directory '" + dir +"', regular file already existed with that name"); 246 } 247 248 } else { 249 if (!dir.mkdirs()) { 250 throw new IOException("Failed to create directory '" + dir+"'"); 251 } 252 } 253 } 254 }