Mercurial > hg > Members > kono > jpf-core
diff src/main/gov/nasa/jpf/util/FileUtils.java @ 0:61d41facf527
initial v8 import (history reset)
author | Peter Mehlitz <Peter.C.Mehlitz@nasa.gov> |
---|---|
date | Fri, 23 Jan 2015 10:14:01 -0800 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/main/gov/nasa/jpf/util/FileUtils.java Fri Jan 23 10:14:01 2015 -0800 @@ -0,0 +1,510 @@ +/* + * Copyright (C) 2014, United States Government, as represented by the + * Administrator of the National Aeronautics and Space Administration. + * All rights reserved. + * + * The Java Pathfinder core (jpf-core) platform is licensed under the + * Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package gov.nasa.jpf.util; + +import java.io.*; +import java.net.URL; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * utility class to find all files matching (possibly hierarchical) + * wildcard path specs + * + * we support single '*' wildcards as in filename matching, plus "**" patterns + * that match all (recursive) subdirectories + */ +// example: List<File> list = findMatches("/U*/p*/tmp/**/*.java"); + +public class FileUtils { + + public static boolean containsWildcards (String pattern) { + return (pattern.indexOf('*') >= 0); + } + + //--- processing wildcard path specs + + public static String[] expandWildcards (String[] pathNames){ + ArrayList<String> list = null; + + if (pathNames == null){ + return new String[0]; + } + + for (int i=0; i<pathNames.length; i++){ + String e = pathNames[i]; + + if (containsWildcards(e)){ + if (list == null){ + list= new ArrayList<String>(pathNames.length + 20); + for (int j=0; j<i; j++){ + list.add(pathNames[j]); + } + } + + for (File f : findMatches(e)){ + list.add(f.getAbsolutePath()); + } + + } else { + if (list != null){ + list.add(e); + } + } + } + + if (list != null){ + return list.toArray(new String[list.size()]); + } else { + return pathNames; + } + } + + + private static List<File> splitPath (String pattern) { + ArrayList<File> list = new ArrayList<File>(); + + for (File f = new File(pattern); f != null; f = f.getParentFile()) { + list.add(f); + } + + Collections.reverse(list); + return list; + } + + private static void addSubdirs (List<File> list, File dir){ + for (File f : dir.listFiles()) { + if (f.isDirectory()){ + list.add(f); + addSubdirs(list, f); + } + } + } + + private static List<File> findMatches (File dir, String pattern) { + ArrayList<File> list = new ArrayList<File>(); + + if (dir.isDirectory()) { + if ("**".equals(pattern)) { // recursively add all subdirectories + addSubdirs(list, dir); + + } else { + StringMatcher sm = new StringMatcher(pattern); + for (File f : dir.listFiles()) { + if (sm.matches(f.getName())) { + list.add(f); + } + } + } + } + + return list; + } + + public static List<File> findMatches (String pattern) { + List<File> pathComponents = splitPath(pattern); + List<File> matches = null; + + for (File f : pathComponents) { + String fname = f.getName(); + if (matches == null) { // first one + if (fname.isEmpty()) { // filesystem root + matches = new ArrayList<File>(); + matches.add(f); + } else { + matches = findMatches(new File(System.getProperty("user.dir")), fname); + } + + } else { + List<File> newMatches = new ArrayList<File>(); + for (File d : matches) { + newMatches.addAll(findMatches(d, fname)); + } + matches = newMatches; + } + + if (matches.isEmpty()) { + return matches; + } + } + return matches; + } + + + //--- URL conversion + + public static URL getURL (String spec){ + try { + // check if there is a protocol specification + if (spec.indexOf("://") >= 0) { + return new URL(spec); + + } else { + File f = new File(spec).getCanonicalFile(); + return f.toURI().toURL(); + } + } catch (Throwable x) { + throw new RuntimeException("illegal pathname: " + spec); + } + } + + public static URL[] getURLs (String[] paths){ + ArrayList<URL> urls = new ArrayList<URL>(); + + for (String p : paths) { + urls.add( getURL(p)); + } + + return urls.toArray(new URL[urls.size()]); + } + + public static URL[] getURLs (List<String> paths){ + ArrayList<URL> urls = new ArrayList<URL>(); + + for (String p : paths) { + urls.add( getURL(p)); + } + + return urls.toArray(new URL[urls.size()]); + } + + + //--- platform specific path conversion + + /** + * turn a mixed path list into a valid Unix path set without drive letters, + * and with '/' and ':' separators. Also remove multiple consecutive separators + * this assumes the path String to be already expanded + */ + public static String asCanonicalUnixPath (String p) { + boolean changed = false; + + int n = p.length(); + char[] buf = new char[n]; + p.getChars(0, n, buf, 0); + + for (int i=0; i<n; i++) { + char c = buf[i]; + if (c == '/' || c == '\\') { + if (c == '\\'){ + buf[i] = '/'; changed = true; + } + + // remove multiple occurrences of dir separators + int i1 = i+1; + if (i1 < n){ + for (c = buf[i1]; i1 < n && (c == '/' || c == '\\'); c = buf[i1]) { + System.arraycopy(buf, i + 2, buf, i1, n - (i + 2)); + n--; + changed = true; + } + } + + } else if (c == ':') { + // strip drive letters - maybe this is trying to be too smart, + // since we only do this for a "...:X:\..." but not a + // "...:X:/...", which could be a valid unix path list + + // is this part of a drive letter spec? + int i1 = i+1; + if (i1<n) { + if (buf[i1] == '\\') { + if (i>0) { + if (i == 1 || (buf[i-2] == ':')){ // strip the drive letter + System.arraycopy(buf, i1, buf, i-1, n - (i1)); + n-=2; + changed = true; + } + } + } + } + + } else if (c == ';'){ + buf[i] = ':'; changed = true; + + } else if (c == ',') { + buf[i] = ':'; changed = true; + } + + if (buf[i] == ':') { // remove multiple occurrences of path separators + int i1 = i+1; + if (i1<n) { + for (c = buf[i1] ;(c == ':' || c == ';' || c == ','); c = buf[i1]){ + System.arraycopy(buf, i+2, buf, i1, n - (i+2)); + n--; + changed = true; + } + } + } + } + + if (changed) { + p = new String(buf, 0, n); + } + + return p; + } + + /** + * turn a mixed path list into a valid Windows path set with drive letters, + * and '\' and ';' separators. Also remove multiple consecutive separators + * this assumes the path String to be already expanded + */ + public static String asCanonicalWindowsPath (String p) { + boolean changed = false; + + int n = p.length(); + char[] buf = new char[n]; + p.getChars(0, n, buf, 0); + + for (int i=0; i<n; i++) { + char c = buf[i]; + if (c == '/' || c == '\\') { + if (c == '/'){ + buf[i] = '\\'; changed = true; + } + + // remove multiple occurrences of dir separators + int i1 = i+1; + if (i1 < n) { + for (c = buf[i1]; i1 < n && (c == '/' || c == '\\'); c = buf[i1]) { + System.arraycopy(buf, i + 2, buf, i1, n - (i + 2)); + n--; + changed = true; + } + } + + } else if (c == ':') { + // is this part of a drive letter spec? + int i1 = i+1; + if (i1<n && (buf[i1] == '\\' || buf[i1] == '/')) { + if (i>0) { + if (i == 1 || (buf[i-2] == ';')){ + continue; + } + } + } + buf[i] = ';'; changed = true; + + } else if (c == ',') { + buf[i] = ';'; changed = true; + } + + if (buf[i] == ';') { // remove multiple occurrences of path separators + int i1 = i+1; + if (i1<n) { + for (c = buf[i1] ;(c == ':' || c == ';' || c == ','); c = buf[i1]){ + System.arraycopy(buf, i+2, buf, i1, n - (i+2)); + n--; + changed = true; + } + } + } + } + + if (changed) { + p = new String(buf, 0, n); + } + + return p; + } + + + public static String asPlatformPath (String p) { + if (File.separatorChar == '/') { // Unix'ish file system + p = asCanonicalUnixPath(p); + } else { // Windows'ish file system + p = asCanonicalWindowsPath(p); + } + + return p; + } + + public static void printFile (PrintWriter pw, File file){ + try { + FileReader fr = new FileReader(file); + BufferedReader r = new BufferedReader(fr); + + String line; + while ((line = r.readLine()) != null){ + pw.println(line); + } + + r.close(); + + } catch (IOException iox){ + pw.println("!! error printing file: " + file.getPath()); + } + } + + public static boolean removeRecursively(File file) { + if (file.exists()) { + File[] childs = file.listFiles(); + + for (File child : childs) { + if (child.isDirectory()){ + removeRecursively(child); + } else { + child.delete(); + } + } + + return file.delete(); + } + + return false; + } + + public static byte[] getContents( File file) throws IOException { + if (file.isFile()){ + long length = file.length(); + byte[] data = new byte[(int)length]; + + FileInputStream is = new FileInputStream(file); + try { + getContents(is, data); + + } catch (IOException iox){ + return null; + + } finally { + is.close(); + } + + return data; + } + + return null; + } + + public static void getContents(InputStream is, byte[] buf) throws IOException { + int nRead = 0; + while (nRead < buf.length) { + int n = is.read(buf, nRead, buf.length - nRead); + if (n < 0) { + throw new IOException("premature end of inputstream: " + buf.length + '/' + nRead); + } + nRead += n; + } + } + + public static String getContentsAsString( File file) throws IOException { + byte[] data = getContents(file); + return new String(data); + } + + public static void setContents(File file, byte[] data) throws IOException { + FileOutputStream os = new FileOutputStream(file); + os.write(data); + os.close(); + } + + public static void setContents(File file, String data) throws IOException { + FileWriter fw = new FileWriter(file); + fw.append(data); + fw.close(); + } + + public static String asCanonicalUserPathName (String path){ + String userHome = System.getProperty("user.home"); + int len = userHome.length(); + if (path.startsWith(userHome) && path.charAt(len) == '/') { + return "${user.home}" + path.substring(len).replace('\\', '/'); + } else { + return path.replace('\\', '/'); + } + } + + public static String asUnixPathName (File file){ + String userHome = System.getProperty("user.home") + File.separatorChar; + int uhLen = userHome.length(); + + String pn = file.getAbsolutePath(); + if (pn.startsWith(userHome)) { + pn = "~/" + pn.substring(uhLen).replace('\\', '/'); + } else { + pn = pn.replace('\\', '/'); + } + return pn; + } + + public static String unixToUserPathName (String unixPathName){ + if (unixPathName.startsWith("~/")){ + return "${user.home}" + unixPathName.substring(1); + } else { + String userHome = System.getProperty("user.home"); + int len = userHome.length(); + if (unixPathName.startsWith(userHome) && unixPathName.charAt(len) == '/'){ + return "${user.home}" + unixPathName.substring(len); + } else { + return unixPathName; + } + } + } + + public static boolean ensureDirs (File file){ + File dir = file.getParentFile(); + if (!dir.isDirectory()){ + return dir.mkdirs(); + } else { + return true; + } + } + + public static String getRelativeUnixPath (File baseDir, File refFile) throws IOException { + String bpn = baseDir.getCanonicalPath().replace('\\', '/'); + String rpn = refFile.getCanonicalPath().replace('\\', '/'); + + int len = Math.min(bpn.length(), rpn.length()); + for (int i = 0, n = 0; i < len; i++) { + char c = bpn.charAt(i); + if (c == '/') { + n = i + 1; + } else if (c != rpn.charAt(i)) { + bpn = bpn.substring(n); + rpn = rpn.substring(n); + break; + } + } + + len = bpn.length(); + String up = ""; + for (int i = 0; i < len; i++) { + if (bpn.charAt(i) == '/') { + up += "../"; + } + } + + String relPath = up + rpn; + return relPath; + } + + public static boolean copyFile (File src, File toDir) throws IOException { + if (src.isFile()) { + File tgt = new File(toDir, src.getName()); + if (tgt.createNewFile()) { + byte[] data = getContents(src); + setContents(tgt, data); + return true; + } + } + + return false; + } +}