View Javadoc

1   package cz.cuni.amis.utils;
2   
3   import java.io.File;
4   import java.util.HashSet;
5   import java.util.Set;
6   
7   import cz.cuni.amis.utils.exception.PogamutException;
8   
9   public class FilePath {
10  	/**
11  	 * Seperator of the classpath entries.
12  	 */
13  	public static final String CLASSPATH_SEPARATOR = ";";
14  	
15  	private static final String ALLOWED_RELATIVE_PATH_CHARS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789._-/";
16  	
17  	private static final Set<String> ALLOWED_RELATIVE_PATH_CHARS_SET = new HashSet<String>();
18  	
19  	static {
20  		for (int i = 0; i < ALLOWED_RELATIVE_PATH_CHARS.length(); ++i) {
21  			ALLOWED_RELATIVE_PATH_CHARS_SET.add(ALLOWED_RELATIVE_PATH_CHARS.substring(i, i+1));
22  		}
23  	}
24  	
25  	/**
26  	 * Checks the 'path' for the presence of ".." + can't start with "/" + enforces use of the {@link FilePath#ALLOWED_RELATIVE_PATH_CHARS}.
27  	 * @param path
28  	 */
29  	public static void checkRelativePath(String path) {
30  		if (path.contains("..")) throw new PogamutException("Path '" + path + "' contains '..' at position " + path.indexOf("..") + " which is forbidden!", FilePath.class);
31  		if (path.startsWith("/")) throw new PogamutException("Path '" + path + "' can't start with '/'.", FilePath.class);
32  		for (int i = 0; i < path.length(); ++i) {
33  			if (!ALLOWED_RELATIVE_PATH_CHARS_SET.contains(path.substring(i, i+1))) {
34  				throw new PogamutException("Path '" + path + "' contains forbidden character at index " + i + " (0-based). Allowed chars are limited to: " + ALLOWED_RELATIVE_PATH_CHARS, FilePath.class);
35  			}
36  		}
37  	}
38  	
39  	/**
40  	 * Treats 'file' as something that points to the file and creates all parent dirs.
41  	 * @param file
42  	 */
43  	public static void makeDirsToFile(File file) {
44  		String parent = file.getParent();
45  		if (parent != null) {
46  			new File(parent).mkdirs();
47  		}
48  	}
49  	
50  	/**
51  	 * Concats all paths sequentially together replacing all backslashes with slashes and watches out for ending of the path1 and beginning of path2 solving
52  	 * "//", "/./", etc. Does not resolves "..".
53  	 * @param paths
54  	 * @return
55  	 */
56  	public static String concatPaths(String... paths) {
57  		if (paths == null) return null;
58  		if (paths.length == 0) return null;
59  		String result = paths[0];
60  		for (int i = 1; i < paths.length; ++i) {
61  			result = concatPaths(result, paths[i]);
62  		}
63  		return result;
64  	}	
65  		
66  	
67  	/**
68  	 * Concats path1 and path2 replacing all backslashes with slashes and watches out for ending of the path1 and beginning of path2 solving
69  	 * "//", "/./", etc. Does not resolves "..".
70  	 * 
71  	 * @param path1
72  	 * @param path2
73  	 * @return
74  	 */
75  	public static String concatPaths(String path1, String path2) {
76  		path1.replace("\\", "/");
77  		path2.replace("\\", "/");
78  		if (path1 == null) {
79  			return path2;
80  		} else
81  		if (path1.equals("./")) {
82  			if (path2 == null) {
83  				return path1;
84  			} else
85  			if (path2.startsWith("/")){
86  				throw new PogamutException("Can't contact path '" + path1 + "' with '" + path2 + "' as path2 starts with '/'.", FilePath.class);
87  			} else {
88  				return path2;
89  			}
90  		} else
91  		if (path1.endsWith("/")) {
92  			if (path2 == null) {
93  				return path1;
94  			} else
95  			if (path2.startsWith("./")) {
96  				return path1 + path2.substring(2);
97  			} else
98  			if (path2.startsWith("/")){
99  				throw new PogamutException("Can't contact path '" + path1 + "' with '" + path2 + "' as path2 starts with '/'.", FilePath.class);
100 			} else {
101 				return path1 + path2;
102 			}
103 		} else {
104 			if (path2 == null) {
105 				return path1;
106 			} else
107 			if (path2.startsWith("./")) {
108 				return path1 + "/" + path2.substring(2);
109 			} else 
110 			if (path2.startsWith("/")){
111 				throw new PogamutException("Can't contact path '" + path1 + "' with '" + path2 + "' as path2 starts with '/'.", FilePath.class);
112 			} else {
113 				return path1 + "/" + path2;
114 			}
115 		}
116 	}
117 	
118 	public static String makeUniform(String file) {
119 		if (file == null) return null;
120 		for (int i = 0; i < file.length(); ++i) {
121 			if (file.charAt(i) == '\\') file = file.substring(0, i) + "/" + file.substring(i+1);
122 		}
123 		file = file.replaceAll("//", "/");
124 		while (file.length() > 0 && file.endsWith("/")) file = file.substring(0, file.length()-1);
125 		while (file.startsWith("./")) file = file.substring(2);
126 		if (file.length() == 0) return null;
127 		
128 		return file;
129 	}
130 
131 }