package org.tizen.dynamicanalyzer.util;
import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
import java.io.IOException;
-import java.nio.file.FileAlreadyExistsException;
-import java.nio.file.FileSystems;
-import java.nio.file.FileVisitResult;
-import java.nio.file.Files;
-import java.nio.file.NoSuchFileException;
-import java.nio.file.Path;
-import java.nio.file.PathMatcher;
-import java.nio.file.Paths;
-import java.nio.file.SimpleFileVisitor;
-import java.nio.file.StandardCopyOption;
-import java.nio.file.attribute.BasicFileAttributes;
+import java.nio.channels.FileChannel;
import java.util.ArrayList;
import java.util.List;
+/**
+ * @author greatim
+ *
+ */
+/**
+ * @author greatim
+ *
+ */
public class FileUtil {
// delete file of given path
}
/**
+ * Converts a standard POSIX Shell globbing pattern into a regular
+ * expression pattern. The result can be used with the standard
+ * {@link java.util.regex} API to recognize strings which match the glob
+ * pattern.
+ * <p/>
+ * See also, the POSIX Shell language:
+ * http://pubs.opengroup.org/onlinepubs/009695399
+ * /utilities/xcu_chap02.html#tag_02_13_01
+ *
+ * @param pattern
+ * A glob pattern.
+ * @return A regex pattern to recognize the given glob pattern.
+ */
+ private static String convertGlobToRegex(String pattern) {
+ StringBuilder sb = new StringBuilder(pattern.length());
+
+ int inGroup = 0;
+ int inClass = 0;
+ int firstIndexInClass = -1;
+ char[] arr = pattern.toCharArray();
+ for (int i = 0; i < arr.length; i++) {
+ char ch = arr[i];
+ switch (ch) {
+ case '\\':
+ if (++i >= arr.length) {
+ sb.append('\\');
+ } else {
+ char next = arr[i];
+ switch (next) {
+ case ',':
+ // escape not needed
+ break;
+ case 'Q':
+ case 'E':
+ // extra escape needed
+ sb.append('\\');
+ default:
+ sb.append('\\');
+ }
+ sb.append(next);
+ }
+ break;
+ case '*':
+ if (inClass == 0)
+ sb.append(".*");
+ else
+ sb.append('*');
+ break;
+ case '?':
+ if (inClass == 0)
+ sb.append('.');
+ else
+ sb.append('?');
+ break;
+ case '[':
+ inClass++;
+ firstIndexInClass = i + 1;
+ sb.append('[');
+ break;
+ case ']':
+ inClass--;
+ sb.append(']');
+ break;
+ case '.':
+ case '(':
+ case ')':
+ case '+':
+ case '|':
+ case '^':
+ case '$':
+ case '@':
+ case '%':
+ if (inClass == 0 || (firstIndexInClass == i && ch == '^'))
+ sb.append('\\');
+ sb.append(ch);
+ break;
+ case '!':
+ if (firstIndexInClass == i)
+ sb.append('^');
+ else
+ sb.append('!');
+ break;
+ case '{':
+ inGroup++;
+ sb.append('(');
+ break;
+ case '}':
+ inGroup--;
+ sb.append(')');
+ break;
+ case ',':
+ if (inGroup > 0)
+ sb.append('|');
+ else
+ sb.append(',');
+ break;
+ default:
+ sb.append(ch);
+ }
+ }
+ return sb.toString();
+ }
+
+ private static void findFileRecursive(File rootPath, String regex, boolean recursive,
+ List<String> result) throws FileNotFoundException, IOException {
+ File[] filesAndDirs = rootPath.listFiles();
+ if (null == filesAndDirs) { // if rootPath is not a directory
+ return;
+ }
+
+ for (File file : filesAndDirs) {
+ if (file.isFile() && file.getName().matches(regex)) {
+ result.add(file.getCanonicalPath()); // add to result if it's
+ // file
+ } else if (recursive) {
+ findFileRecursive(file, regex, recursive, result); // recursive
+ }
+ }
+ }
+
+ /**
* Search files in given directory with file name glob pattern. Returned
- * file paths are relative paths to given directory
- * <p>
- * For example, if search file with "*.txt" glob pattern and "/home/user/"
- * target directory for "/home/user/aaa/bbb/ccc.txt", result file path in
- * the list is "aaa/bbb/ccc.txt"
+ * file paths are canonical paths to given directory *
*
* @param dirPath
* root path of searching
* @param fileToken
* glob pattern of file name
- * @return relative file path list
+ * @return canonical file path list
*/
public static List<String> findFilesInDir(String dirPath, String fileToken) {
- final List<String> resultFiles = new ArrayList<String>();
-
- final Path startingDir = Paths.get(dirPath).toAbsolutePath();
- final PathMatcher matcher = FileSystems.getDefault().getPathMatcher("glob:" + fileToken);
- try {
- Files.walkFileTree(startingDir, new SimpleFileVisitor<Path>() {
- private void find(Path path) {
- Path filename = path.getFileName();
- if (filename != null && matcher.matches(filename)) {
- Path relativePath = startingDir.relativize(path);
- resultFiles.add(relativePath.toString());
- }
- }
+ List<String> resultFiles = new ArrayList<String>();
- @Override
- public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
- find(dir);
- return FileVisitResult.CONTINUE;
- }
-
- @Override
- public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
- find(file);
- return FileVisitResult.CONTINUE;
- }
- });
- } catch (NoSuchFileException e) {
- Logger.warning("starting directory cannot be found");
- } catch (IOException e) {
- e.printStackTrace();
+ String regex = convertGlobToRegex(fileToken);
+ File startingDir = new File(dirPath);
+ if (startingDir.exists()) {
+ try {
+ findFileRecursive(startingDir, regex, true, resultFiles);
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
}
return resultFiles;
}
- // return destination file path
- // if failed, return null
- public static String copyFileToDir(String src, String destDir, boolean overwrite)
- throws FileAlreadyExistsException {
+ /**
+ * copy a single file to destination directory, if file with same name
+ * exist, overwrite it.
+ *
+ * @param src
+ * source file path
+ * @param destDir
+ * destination directory path
+ * @return destination file path if coping succeed, return null otherwise..
+ */
+ public static String copyFileToDir(String src, String destDir) throws IOException {
File srcfile = new File(src);
if (srcfile.isFile()) {
String srcfilename = srcfile.getName();
} else {
dest = destDir + File.separator + srcfilename;
}
-
File destfile = new File(dest);
- try {
- if (overwrite) {
- Files.copy(srcfile.toPath(), destfile.toPath(),
- StandardCopyOption.REPLACE_EXISTING);
- } else {
- Files.copy(srcfile.toPath(), destfile.toPath());
+ if (srcfile.getCanonicalPath().equals(destfile.getCanonicalPath())) {
+ throw new IOException(
+ "File copy error. Destination directory is the parent directory of source file");
+ }
+
+ File destdir = new File(destDir);
+ if (!destdir.exists()) {
+ if (!destdir.mkdirs()) {
+ throw new IOException("File copy error. Cannot create directory - "
+ + destdir.getAbsolutePath());
}
- return dest;
- } catch (IOException e) {
- e.printStackTrace();
}
+
+ copyFile(srcfile, destfile);
+ return dest;
+ } else {
+ return null;
}
+ }
- return null;
+ /**
+ * copy a single file to destination file path
+ *
+ * @param source
+ * source file
+ * @param dest
+ * destination file
+ */
+ public static void copyFile(File source, File dest) throws IOException {
+ FileChannel inputChannel = null;
+ FileChannel outputChannel = null;
+ try {
+ inputChannel = new FileInputStream(source).getChannel();
+ outputChannel = new FileOutputStream(dest).getChannel();
+ outputChannel.transferFrom(inputChannel, 0, inputChannel.size());
+ } finally {
+ CommonUtil.tryClose(inputChannel, outputChannel);
+ }
}
}
import java.io.BufferedWriter;
import java.io.File;
import java.io.IOException;
-import java.nio.file.FileAlreadyExistsException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
String from = binData.getDebugRpmPath();
if (from != null && !from.isEmpty()) {
try {
- debugRpmPath = FileUtil.copyFileToDir(from, rpmPath, true);
+ debugRpmPath = FileUtil.copyFileToDir(from, rpmPath);
if (debugRpmPath == null) {
return null;
}
- } catch (FileAlreadyExistsException e) {
+ } catch (IOException e) {
e.printStackTrace();
return null;
}
from = binData.getSourceRpmPath();
if (from != null && !from.isEmpty()) {
try {
- debugRpmSourcePath = FileUtil.copyFileToDir(from, rpmPath, true);
- } catch (FileAlreadyExistsException e) {
+ debugRpmSourcePath = FileUtil.copyFileToDir(from, rpmPath);
+ } catch (IOException e) {
e.printStackTrace();
}
}
String debugCandidate = "*" + binName + ".debug";
List<String> debugfilelist = FileUtil.findFilesInDir(extractPath, debugCandidate);
if (debugfilelist.size() > 0) {
- String fullpath;
- if (extractPath.endsWith(File.separator)) {
- fullpath = extractPath + debugfilelist.get(0);
- } else {
- fullpath = extractPath + File.separator + debugfilelist.get(0);
- }
- binData.setDebugFilePath(fullpath);
+ binData.setDebugFilePath(debugfilelist.get(0));
// find real source file path
String debugSourceRpmPath = binData.getSourceRpmPath();
} else if (debugRpmPath.contains(RpmUtil.DEBUG)) {
List<String> debugfilelist = FileUtil.findFilesInDir(extractPath, binName);
if (debugfilelist.size() > 0) {
- String fullpath;
- if (extractPath.endsWith(File.separator)) {
- fullpath = extractPath + debugfilelist.get(0);
- } else {
- fullpath = extractPath + File.separator + debugfilelist.get(0);
- }
- binData.setDebugFilePath(fullpath);
+ binData.setDebugFilePath(debugfilelist.get(0));
} else {
binData.setDebugFilePath(null);
}
if (binName != null) {
// get file list in rpm package and find target binary name
for (int i = 0; i < rpmlist.size(); i++) {
- String rpmpath = rootPath + rpmlist.get(i);
+ String rpmpath = rpmlist.get(i);
List<String> filelist = RpmUtil.getFileListInRpm(rpmpath);
int filesize = filelist.size();
boolean bFound = false;