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.IOException; 024 import java.io.InputStream; 025 import java.io.OutputStream; 026 027 /** 028 * @version $Revision: 661435 $ 029 */ 030 public final class IOHelper { 031 protected static final int MAX_DIR_NAME_LENGTH; 032 protected static final int MAX_FILE_NAME_LENGTH; 033 private static final int DEFAULT_BUFFER_SIZE = 4096; 034 private IOHelper() { 035 } 036 037 public static String getDefaultDataDirectory() { 038 return getDefaultDirectoryPrefix() + "activemq-data"; 039 } 040 041 public static String getDefaultStoreDirectory() { 042 return getDefaultDirectoryPrefix() + "amqstore"; 043 } 044 045 /** 046 * Allows a system property to be used to overload the default data 047 * directory which can be useful for forcing the test cases to use a target/ 048 * prefix 049 */ 050 public static String getDefaultDirectoryPrefix() { 051 try { 052 return System.getProperty("org.apache.activemq.default.directory.prefix", ""); 053 } catch (Exception e) { 054 return ""; 055 } 056 } 057 058 /** 059 * Converts any string into a string that is safe to use as a file name. 060 * The result will only include ascii characters and numbers, and the "-","_", and "." characters. 061 * 062 * @param name 063 * @return 064 */ 065 public static String toFileSystemDirectorySafeName(String name) { 066 return toFileSystemSafeName(name, true, MAX_DIR_NAME_LENGTH); 067 } 068 069 public static String toFileSystemSafeName(String name) { 070 return toFileSystemSafeName(name, false, MAX_FILE_NAME_LENGTH); 071 } 072 073 /** 074 * Converts any string into a string that is safe to use as a file name. 075 * The result will only include ascii characters and numbers, and the "-","_", and "." characters. 076 * 077 * @param name 078 * @param dirSeparators 079 * @param maxFileLength 080 * @return 081 */ 082 public static String toFileSystemSafeName(String name,boolean dirSeparators,int maxFileLength) { 083 int size = name.length(); 084 StringBuffer rc = new StringBuffer(size * 2); 085 for (int i = 0; i < size; i++) { 086 char c = name.charAt(i); 087 boolean valid = c >= 'a' && c <= 'z'; 088 valid = valid || (c >= 'A' && c <= 'Z'); 089 valid = valid || (c >= '0' && c <= '9'); 090 valid = valid || (c == '_') || (c == '-') || (c == '.') || (c=='#') 091 ||(dirSeparators && ( (c == '/') || (c == '\\'))); 092 093 if (valid) { 094 rc.append(c); 095 } else { 096 // Encode the character using hex notation 097 rc.append('#'); 098 rc.append(HexSupport.toHexFromInt(c, true)); 099 } 100 } 101 String result = rc.toString(); 102 if (result.length() > maxFileLength) { 103 result = result.substring(result.length()-maxFileLength,result.length()); 104 } 105 return result; 106 } 107 108 public static boolean deleteFile(File fileToDelete) { 109 if (fileToDelete == null || !fileToDelete.exists()) { 110 return true; 111 } 112 boolean result = deleteChildren(fileToDelete); 113 result &= fileToDelete.delete(); 114 return result; 115 } 116 117 public static boolean deleteChildren(File parent) { 118 if (parent == null || !parent.exists()) { 119 return false; 120 } 121 boolean result = true; 122 if (parent.isDirectory()) { 123 File[] files = parent.listFiles(); 124 if (files == null) { 125 result = false; 126 } else { 127 for (int i = 0; i < files.length; i++) { 128 File file = files[i]; 129 if (file.getName().equals(".") 130 || file.getName().equals("..")) { 131 continue; 132 } 133 if (file.isDirectory()) { 134 result &= deleteFile(file); 135 } else { 136 result &= file.delete(); 137 } 138 } 139 } 140 } 141 142 return result; 143 } 144 145 146 public static void moveFile(File src, File targetDirectory) throws IOException { 147 if (!src.renameTo(new File(targetDirectory, src.getName()))) { 148 throw new IOException("Failed to move " + src + " to " + targetDirectory); 149 } 150 } 151 152 public static void copyFile(File src, File dest) throws IOException { 153 FileInputStream fileSrc = new FileInputStream(src); 154 FileOutputStream fileDest = new FileOutputStream(dest); 155 copyInputStream(fileSrc, fileDest); 156 } 157 158 public static void copyInputStream(InputStream in, OutputStream out) throws IOException { 159 byte[] buffer = new byte[DEFAULT_BUFFER_SIZE]; 160 int len = in.read(buffer); 161 while (len >= 0) { 162 out.write(buffer, 0, len); 163 len = in.read(buffer); 164 } 165 in.close(); 166 out.close(); 167 } 168 169 static { 170 MAX_DIR_NAME_LENGTH = Integer.valueOf(System.getProperty("MaximumDirNameLength","200")).intValue(); 171 MAX_FILE_NAME_LENGTH = Integer.valueOf(System.getProperty("MaximumFileNameLength","64")).intValue(); 172 } 173 174 175 public static void mkdirs(File dir) throws IOException { 176 if (dir.exists()) { 177 if (!dir.isDirectory()) { 178 throw new IOException("Failed to create directory '" + dir +"', regular file already existed with that name"); 179 } 180 181 } else { 182 if (!dir.mkdirs()) { 183 throw new IOException("Failed to create directory '" + dir+"'"); 184 } 185 } 186 } 187 }