|
38 | 38 | * @author <a href="mailto:jefft@apache.org">Jeff Turner</a> |
39 | 39 | * @author Matthew Hawthorne |
40 | 40 | * @author <a href="mailto:jeremias@apache.org">Jeremias Maerki</a> |
41 | | - * @version $Id: FilenameUtils.java,v 1.7 2004/02/23 04:35:59 bayard Exp $ |
| 41 | + * @version $Id: FilenameUtils.java,v 1.8 2004/03/12 21:58:59 jeremias Exp $ |
42 | 42 | */ |
43 | 43 | public class FilenameUtils { |
44 | 44 |
|
@@ -263,38 +263,61 @@ public static String normalize( String path) { |
263 | 263 | } |
264 | 264 |
|
265 | 265 | /** |
266 | | - * Will concatenate 2 paths. Paths with <code>..</code> will be |
267 | | - * properly handled. |
268 | | - * <p>Eg.,<br /> |
| 266 | + * Will concatenate 2 paths. Paths with <code>..</code> will be |
| 267 | + * properly handled. The path separator between the 2 paths is the |
| 268 | + * system default path separator. |
| 269 | + * |
| 270 | + * <p>Eg. on UNIX,<br /> |
269 | 271 | * <code>/a/b/c</code> + <code>d</code> = <code>/a/b/d</code><br /> |
270 | 272 | * <code>/a/b/c</code> + <code>../d</code> = <code>/a/d</code><br /> |
271 | 273 | * </p> |
272 | 274 | * |
| 275 | + * <p>Eg. on Microsoft Windows,<br /> |
| 276 | + * <code>C:\a\b\c</code> + <code>d</code> = <code>C:\a\b\d</code><br /> |
| 277 | + * <code>C:\a\b\c</code> + <code>..\d</code> = <code>C:\a\d</code><br /> |
| 278 | + * <code>/a/b/c</code> + <code>d</code> = <code>/a/b\d</code><br /> |
| 279 | + * </p> |
| 280 | + * |
273 | 281 | * Thieved from Tomcat sources... |
274 | 282 | * |
| 283 | + * @param lookupPath the base path to attach to |
| 284 | + * @param path path the second path to attach to the first |
275 | 285 | * @return The concatenated paths, or null if error occurs |
276 | 286 | */ |
277 | 287 | public static String catPath( String lookupPath, String path) { |
278 | 288 | // Cut off the last slash and everything beyond |
279 | | - int index = lookupPath.lastIndexOf("/"); |
| 289 | + int index = indexOfLastPathSeparator(lookupPath); |
280 | 290 | String lookup = lookupPath.substring(0, index); |
281 | 291 | String pth = path; |
282 | 292 |
|
283 | 293 | // Deal with .. by chopping dirs off the lookup path |
284 | | - while (pth.startsWith("../")) { |
| 294 | + while (pth.startsWith("../") || pth.startsWith("..\\")) { |
285 | 295 | if (lookup.length() > 0) { |
286 | | - index = lookup.lastIndexOf("/"); |
| 296 | + index = indexOfLastPathSeparator(lookup); |
287 | 297 | lookup = lookup.substring(0, index); |
288 | 298 | } else { |
289 | 299 | // More ..'s than dirs, return null |
290 | 300 | return null; |
291 | 301 | } |
292 | 302 |
|
293 | | - index = pth.indexOf("../") + 3; |
294 | | - pth = pth.substring(index); |
| 303 | + pth = pth.substring(3); |
295 | 304 | } |
296 | 305 |
|
297 | | - return new StringBuffer(lookup).append("/").append(pth).toString(); |
| 306 | + return new StringBuffer(lookup).append(File.separator).append(pth).toString(); |
| 307 | + } |
| 308 | + |
| 309 | + /** |
| 310 | + * Return the index of the last 'path separator' character. The 'path separator' |
| 311 | + * character is '/' for UNIX systems and '\' for Microsoft Windows systems. |
| 312 | + * |
| 313 | + * @param path The path to find the last path separator in |
| 314 | + * @return The index of the last 'path separator' character, or -1 if there |
| 315 | + * is no such character. |
| 316 | + */ |
| 317 | + public static int indexOfLastPathSeparator(String path) { |
| 318 | + int lastUnixPos = path.lastIndexOf('/'); |
| 319 | + int lastWindowsPos = path.lastIndexOf('\\'); |
| 320 | + return Math.max(lastUnixPos, lastWindowsPos); |
298 | 321 | } |
299 | 322 |
|
300 | 323 | /** |
|
0 commit comments