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 }