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 String ALLOWED_FILE_NAME_CHARS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789._-";
18  	
19  	private static final Set<String> ALLOWED_RELATIVE_PATH_CHARS_SET = new HashSet<String>();
20  	
21  	static {
22  		for (int i = 0; i < ALLOWED_RELATIVE_PATH_CHARS.length(); ++i) {
23  			ALLOWED_RELATIVE_PATH_CHARS_SET.add(ALLOWED_RELATIVE_PATH_CHARS.substring(i, i+1));
24  		}
25  	}
26  	
27  	public static String getValidFileName(String fileName) {
28  		if (fileName == null) return null;
29  		StringBuffer sb = new StringBuffer(fileName.length());
30  		for (int i = 0; i < fileName.length(); ++i) {
31  			if (ALLOWED_FILE_NAME_CHARS.contains(String.valueOf(fileName.charAt(i)))) sb.append(fileName.charAt(i));
32  			else sb.append("_");
33  		}
34  		return sb.toString();
35  	}
36  	
37  	/**
38  	 * Checks the 'path' for the presence of ".." + can't start with "/" + enforces use of the {@link FilePath#ALLOWED_RELATIVE_PATH_CHARS}.
39  	 * @param path
40  	 */
41  	public static void checkRelativePath(String path) {
42  		if (path.contains("..")) throw new PogamutException("Path '" + path + "' contains '..' at position " + path.indexOf("..") + " which is forbidden!", FilePath.class);
43  		if (path.startsWith("/")) throw new PogamutException("Path '" + path + "' can't start with '/'.", FilePath.class);
44  		for (int i = 0; i < path.length(); ++i) {
45  			if (!ALLOWED_RELATIVE_PATH_CHARS_SET.contains(path.substring(i, i+1))) {
46  				throw new PogamutException("Path '" + path + "' contains forbidden character at index " + i + " (0-based). Allowed chars are limited to: " + ALLOWED_RELATIVE_PATH_CHARS, FilePath.class);
47  			}
48  		}
49  	}
50  	
51  	/**
52  	 * Treats 'file' as something that points to the file and creates all parent dirs.
53  	 * @param file
54  	 */
55  	public static void makeDirsToFile(File file) {
56  		String parent = file.getParent();
57  		if (parent != null) {
58  			new File(parent).mkdirs();
59  		}
60  	}
61  	
62  	/**
63  	 * Concats all paths sequentially together replacing all backslashes with slashes and watches out for ending of the path1 and beginning of path2 solving
64  	 * "//", "/./", etc. Does not resolves "..".
65  	 * @param paths
66  	 * @return
67  	 */
68  	public static String concatPaths(String... paths) {
69  		if (paths == null) return null;
70  		if (paths.length == 0) return null;
71  		String result = paths[0];
72  		for (int i = 1; i < paths.length; ++i) {
73  			result = concatPaths(result, paths[i]);
74  		}
75  		return result;
76  	}	
77  		
78  	
79  	/**
80  	 * Concats path1 and path2 replacing all backslashes with slashes and watches out for ending of the path1 and beginning of path2 solving
81  	 * "//", "/./", etc. Does not resolves "..".
82  	 * 
83  	 * @param path1
84  	 * @param path2
85  	 * @return
86  	 */
87  	public static String concatPaths(String path1, String path2) {
88  		path1.replace("\\", "/");
89  		path2.replace("\\", "/");
90  		if (path1 == null) {
91  			return path2;
92  		} else
93  		if (path1.equals("./")) {
94  			if (path2 == null) {
95  				return path1;
96  			} else
97  			if (path2.startsWith("/")){
98  				throw new PogamutException("Can't contact path '" + path1 + "' with '" + path2 + "' as path2 starts with '/'.", FilePath.class);
99  			} else {
100 				return path2;
101 			}
102 		} else
103 		if (path1.endsWith("/")) {
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 		} else {
116 			if (path2 == null) {
117 				return path1;
118 			} else
119 			if (path2.startsWith("./")) {
120 				return path1 + "/" + path2.substring(2);
121 			} else 
122 			if (path2.startsWith("/")){
123 				throw new PogamutException("Can't contact path '" + path1 + "' with '" + path2 + "' as path2 starts with '/'.", FilePath.class);
124 			} else {
125 				return path1 + "/" + path2;
126 			}
127 		}
128 	}
129 	
130 	public static String makeUniform(String file) {
131 		if (file == null) return null;
132 		for (int i = 0; i < file.length(); ++i) {
133 			if (file.charAt(i) == '\\') file = file.substring(0, i) + "/" + file.substring(i+1);
134 		}
135 		file = file.replaceAll("//", "/");
136 		while (file.length() > 0 && file.endsWith("/")) file = file.substring(0, file.length()-1);
137 		while (file.startsWith("./")) file = file.substring(2);
138 		if (file.length() == 0) return null;
139 		
140 		return file;
141 	}
142 
143 }