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.kahadb.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: 712224 $
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 }