gvsig-tools / org.gvsig.tools / library / trunk / org.gvsig.tools / org.gvsig.tools.lib / src / main / java / org / gvsig / tools / persistence / impl / FileTools.java @ 1249
History | View | Annotate | Download (5.07 KB)
1 | 993 | jjdelcerro | package org.gvsig.tools.persistence.impl; |
---|---|---|---|
2 | |||
3 | import java.io.File; |
||
4 | 994 | jjdelcerro | import org.apache.commons.io.FilenameUtils; |
5 | 1249 | jjdelcerro | import org.slf4j.Logger; |
6 | import org.slf4j.LoggerFactory; |
||
7 | 993 | jjdelcerro | |
8 | public class FileTools { |
||
9 | 1249 | jjdelcerro | private static Logger logger = LoggerFactory.getLogger(FileTools.class); |
10 | 993 | jjdelcerro | |
11 | static File relativizeFile(File rootFolder, File file) { |
||
12 | if (rootFolder == null) { |
||
13 | return file;
|
||
14 | } |
||
15 | if (file == null) { |
||
16 | return null; |
||
17 | } |
||
18 | |||
19 | boolean isDir = false; |
||
20 | // isDir = file.isDirectory();
|
||
21 | isDir = rootFolder.isDirectory(); |
||
22 | String basePath = rootFolder.getAbsolutePath();
|
||
23 | 1249 | jjdelcerro | if( basePath == null ) { |
24 | logger.warn("Can't get absolute path, no relativize file '"+rootFolder.toString()+"'."); |
||
25 | return file;
|
||
26 | } |
||
27 | 993 | jjdelcerro | |
28 | String targetPath = FilenameUtils.normalize(file.getPath());
|
||
29 | 1249 | jjdelcerro | if( targetPath == null ) { |
30 | logger.warn("Can't normalize path, no relativize file '"+file.getAbsolutePath()+"'."); |
||
31 | return file;
|
||
32 | } |
||
33 | 993 | jjdelcerro | |
34 | String pathSeparator = File.separator; |
||
35 | // We need the -1 argument to split to make sure we get a trailing
|
||
36 | // "" token if the base ends in the path separator and is therefore
|
||
37 | // a directory. We require directory paths to end in the path
|
||
38 | // separator -- otherwise they are indistinguishable from files.
|
||
39 | 1249 | jjdelcerro | String pathSeparatorQuoted = Pattern_quote(pathSeparator);
|
40 | 993 | jjdelcerro | |
41 | 1249 | jjdelcerro | String[] base = basePath.split(pathSeparatorQuoted, -1); |
42 | String[] target = targetPath.split(pathSeparatorQuoted, 0); |
||
43 | |||
44 | 993 | jjdelcerro | // First get all the common elements. Store them as a string,
|
45 | // and also count how many of them there are.
|
||
46 | String common = ""; |
||
47 | int commonIndex = 0; |
||
48 | for (int i = 0; i < target.length && i < base.length; i++) { |
||
49 | if (target[i].equals(base[i])) {
|
||
50 | common += target[i] + pathSeparator; |
||
51 | commonIndex++; |
||
52 | } else
|
||
53 | break;
|
||
54 | } |
||
55 | |||
56 | if (commonIndex == 0) { |
||
57 | // Whoops -- not even a single common path element. This most
|
||
58 | // likely indicates differing drive letters, like C: and D:.
|
||
59 | // These paths cannot be relativized. Return the target path.
|
||
60 | return file;
|
||
61 | // This should never happen when all absolute paths
|
||
62 | // begin with / as in *nix.
|
||
63 | } |
||
64 | |||
65 | String relative = ""; |
||
66 | if (base.length == commonIndex) {
|
||
67 | // Comment this out if you prefer that a relative path not start
|
||
68 | // with ./
|
||
69 | relative = "." + pathSeparator;
|
||
70 | } else {
|
||
71 | int numDirsUp = base.length - commonIndex - (isDir ? 0 : 1); |
||
72 | // only subtract 1 if it is a file.
|
||
73 | // The number of directories we have to backtrack is the length of
|
||
74 | // the base path MINUS the number of common path elements, minus
|
||
75 | // one because the last element in the path isn't a directory.
|
||
76 | for (int i = 1; i <= (numDirsUp); i++) { |
||
77 | relative += ".." + pathSeparator;
|
||
78 | } |
||
79 | } |
||
80 | // if we are comparing directories then we
|
||
81 | if (targetPath.length() > common.length()) {
|
||
82 | // it's OK, it isn't a directory
|
||
83 | relative += targetPath.substring(common.length()); |
||
84 | } |
||
85 | |||
86 | return new File(relative); |
||
87 | } |
||
88 | |||
89 | static File derelativizeFile(File rootFolder, File file ) { |
||
90 | 1079 | jbadia | if(rootFolder == null || file == null){ |
91 | return file;
|
||
92 | } |
||
93 | 993 | jjdelcerro | if (file.isAbsolute()) {
|
94 | return file;
|
||
95 | } |
||
96 | File f = new File(rootFolder, file.getPath()).getAbsoluteFile(); |
||
97 | String targetPath = FilenameUtils.normalize(f.getPath());
|
||
98 | return new File(targetPath); |
||
99 | } |
||
100 | |||
101 | static boolean isInDifferentDrive(File rootFolder, File file) { |
||
102 | |||
103 | if (rootFolder == null) { |
||
104 | return false; |
||
105 | } |
||
106 | |||
107 | if (file == null) { |
||
108 | return false; |
||
109 | } |
||
110 | String basePath = rootFolder.getAbsolutePath();
|
||
111 | String targetPath = file.getPath();
|
||
112 | String pathSeparator = File.separator; |
||
113 | // We need the -1 argument to split to make sure we get a trailing
|
||
114 | // "" token if the base ends in the path separator and is therefore
|
||
115 | // a directory. We require directory paths to end in the path
|
||
116 | // separator -- otherwise they are indistinguishable from files.
|
||
117 | 994 | jjdelcerro | String[] base = basePath.split(Pattern_quote(pathSeparator), -1); |
118 | String[] target = targetPath.split(Pattern_quote(pathSeparator), 0); |
||
119 | 993 | jjdelcerro | /*
|
120 | * If first component is different then they are different
|
||
121 | * drives. In Unix-type file systems, the first for both
|
||
122 | * should be "" so this will not happen
|
||
123 | */
|
||
124 | return !target[0].equals(base[0]); |
||
125 | } |
||
126 | |||
127 | 994 | jjdelcerro | |
128 | private static String Pattern_quote(String str) { |
||
129 | int eInd = str.indexOf("\\E"); |
||
130 | if (eInd < 0) { |
||
131 | // No need to handle backslashes.
|
||
132 | return "\\Q" + str + "\\E"; |
||
133 | } |
||
134 | |||
135 | StringBuffer sb = new StringBuffer(str.length() + 16); |
||
136 | sb.append("\\Q"); // start quote |
||
137 | |||
138 | int pos = 0; |
||
139 | do {
|
||
140 | // A backslash is quoted by another backslash;
|
||
141 | // 'E' is not needed to be quoted.
|
||
142 | sb.append(str.substring(pos, eInd)) |
||
143 | .append("\\E" + "\\\\" + "E" + "\\Q"); |
||
144 | pos = eInd + 2;
|
||
145 | } while ((eInd = str.indexOf("\\E", pos)) >= 0); |
||
146 | |||
147 | sb.append(str.substring(pos, str.length())) |
||
148 | .append("\\E"); // end quote |
||
149 | return sb.toString();
|
||
150 | } |
||
151 | |||
152 | 993 | jjdelcerro | } |