|
@@ -1,24 +1,36 @@ |
1 |
1 |
|
package com.esotericsoftware.utils; |
2 |
2 |
|
|
|
3 |
+ |
import java.io.*; |
|
4 |
+ |
|
3 |
5 |
|
import com.esotericsoftware.scar.*; |
4 |
6 |
|
|
5 |
7 |
|
public class FileSupport |
6 |
8 |
|
{ |
|
9 |
+ |
public static final String WINDOWS_UNC_PATH_PREFIX = "\\\\"; |
|
10 |
+ |
|
|
11 |
+ |
public static String getWindowsDriveIndicator( String path ) |
|
12 |
+ |
{ |
|
13 |
+ |
return ((path.length() > 1) && (path.charAt( 1 ) == ':')) ? path.substring( 0, 2 ).toUpperCase() : ""; |
|
14 |
+ |
} |
|
15 |
+ |
|
|
16 |
+ |
public static String removeFromFront( String pToRemove, String path ) |
|
17 |
+ |
{ |
|
18 |
+ |
return (pToRemove.length() == 0) ? path : path.substring( pToRemove.length() ); |
|
19 |
+ |
} |
|
20 |
+ |
|
7 |
21 |
|
public static String normalizePath( IFileSystem pFileSystem, String path ) |
8 |
22 |
|
{ |
9 |
23 |
|
path = path.trim(); |
10 |
24 |
|
String zPrefix = ""; |
11 |
25 |
|
if ( pFileSystem.isWindows() ) |
12 |
26 |
|
{ |
13 |
|
- |
if ( path.startsWith( "\\\\" ) ) |
|
27 |
+ |
if ( path.startsWith( WINDOWS_UNC_PATH_PREFIX ) ) |
14 |
28 |
|
{ |
15 |
|
- |
zPrefix = "\\\\"; |
16 |
|
- |
path = path.substring( 2 ).trim(); |
|
29 |
+ |
path = removeFromFront( zPrefix = WINDOWS_UNC_PATH_PREFIX, path ).trim(); |
17 |
30 |
|
} |
18 |
|
- |
else if ( (path.length() > 1) && (path.charAt( 1 ) == ':') ) // Handle Drive Letter |
|
31 |
+ |
else |
19 |
32 |
|
{ |
20 |
|
- |
zPrefix = path.substring( 0, 2 ).toUpperCase(); |
21 |
|
- |
path = path.substring( 2 ).trim(); |
|
33 |
+ |
path = removeFromFront( zPrefix = getWindowsDriveIndicator( path ), path ).trim(); // Handle Drive Letter |
22 |
34 |
|
} |
23 |
35 |
|
} |
24 |
36 |
|
path = path.trim(); |
|
@@ -94,40 +106,82 @@ |
94 |
106 |
|
return path.substring( 0, pAt + 1 ) + path.substring( zEnd ); |
95 |
107 |
|
} |
96 |
108 |
|
|
97 |
|
- |
public static boolean isAbsoluteNormalizedPath( IFileSystem pFileSystem, String pCanonicalDirForWindowDriveLetterSourceRelativeness, String path ) |
|
109 |
+ |
public static boolean isAbsoluteNormalizedPath( IFileSystem pFileSystem, String pCanonicalParentDirIfPathRelativeForWindowsDriveLetter, String path ) |
98 |
110 |
|
{ |
99 |
|
- |
if ( hasWindowsDriveLetter( pFileSystem, path ) ) // Handle Drive Letter |
|
111 |
+ |
if ( pFileSystem.isWindows() ) |
100 |
112 |
|
{ |
101 |
|
- |
if ( !pCanonicalDirForWindowDriveLetterSourceRelativeness.substring( 0, 2 ).equalsIgnoreCase( path.substring( 0, 2 ) ) ) |
|
113 |
+ |
if ( path.startsWith( WINDOWS_UNC_PATH_PREFIX ) ) |
|
114 |
+ |
{ |
|
115 |
+ |
return true; |
|
116 |
+ |
} |
|
117 |
+ |
String zDriveIndicator = getWindowsDriveIndicator( path ); |
|
118 |
+ |
if ( zDriveIndicator.length() != 0 ) // Handle Drive Letter |
102 |
119 |
|
{ |
103 |
|
- |
return true; // Has Drive Letter and it is NOT the same as the 'CanonicalDirForWindowDriveLetterSourceRelativeness' |
|
120 |
+ |
if ( !pCanonicalParentDirIfPathRelativeForWindowsDriveLetter.startsWith( zDriveIndicator ) || !pFileSystem.canonicalCurrentPath().startsWith( zDriveIndicator ) ) |
|
121 |
+ |
{ |
|
122 |
+ |
return true; // Has Drive Letter and it is NOT the same both the 'CanonicalDirForWindowDriveLetterSourceRelativeness' && pFileSystem.canonicalCurrentPath() |
|
123 |
+ |
} |
|
124 |
+ |
path = removeFromFront( zDriveIndicator, path ); |
104 |
125 |
|
} |
105 |
|
- |
path = path.substring( 2 ); |
106 |
126 |
|
} |
107 |
|
- |
// todo: ... |
108 |
|
- |
|
109 |
|
- |
return false; |
|
127 |
+ |
return (path.length() > 0) && (path.charAt( 0 ) == pFileSystem.separatorChar()); |
110 |
128 |
|
} |
111 |
129 |
|
|
112 |
130 |
|
public static String canonicalizeNormalizedPath( IFileSystem pFileSystem, String pCanonicalParentDirIfPathRelative, String path ) |
|
131 |
+ |
throws IOException |
113 |
132 |
|
{ |
114 |
|
- |
if ( hasWindowsDriveLetter( pFileSystem, path ) ) // Handle Drive Letter |
|
133 |
+ |
if ( !pFileSystem.isWindows() ) |
115 |
134 |
|
{ |
116 |
|
- |
if ( pCanonicalParentDirIfPathRelative.substring( 0, 2 ).equalsIgnoreCase( path.substring( 0, 2 ) ) ) |
|
135 |
+ |
if ( !isAbsoluteNormalizedPath( pFileSystem, pCanonicalParentDirIfPathRelative, path ) ) |
117 |
136 |
|
{ |
118 |
|
- |
path = path.substring( 2 ); |
|
137 |
+ |
path = normalizePath( pFileSystem, pCanonicalParentDirIfPathRelative + pFileSystem.separatorChar() + path ); |
119 |
138 |
|
} |
|
139 |
+ |
return canonicalizeAbsoluteNormalizedPath( pFileSystem, path ); |
120 |
140 |
|
} |
121 |
|
- |
if ( !isAbsoluteNormalizedPath( pFileSystem, pCanonicalParentDirIfPathRelative, path ) ) |
|
141 |
+ |
// Windows! |
|
142 |
+ |
if ( path.startsWith( WINDOWS_UNC_PATH_PREFIX ) ) |
122 |
143 |
|
{ |
123 |
|
- |
path = normalizePath( pFileSystem, pCanonicalParentDirIfPathRelative + pFileSystem.separatorChar() + path ); |
|
144 |
+ |
return canonicalizeAbsoluteNormalizedPath( pFileSystem, path ); |
124 |
145 |
|
} |
125 |
|
- |
// canonicalize |
126 |
|
- |
return null; // todo... |
|
146 |
+ |
String zDriveIndicator = getWindowsDriveIndicator( path ); |
|
147 |
+ |
if ( !isAbsoluteNormalizedPath( pFileSystem, pCanonicalParentDirIfPathRelative, path ) ) // Relative! |
|
148 |
+ |
{ |
|
149 |
+ |
path = normalizePath( pFileSystem, pCanonicalParentDirIfPathRelative + pFileSystem.separatorChar() + removeFromFront( zDriveIndicator, path ) ); |
|
150 |
+ |
return canonicalizeAbsoluteNormalizedPath( pFileSystem, path ); |
|
151 |
+ |
} |
|
152 |
+ |
// Absolute |
|
153 |
+ |
if ( zDriveIndicator.length() == 0 ) // to "default" Drive |
|
154 |
+ |
{ |
|
155 |
+ |
return canonicalizeAbsoluteNormalizedPath( pFileSystem, path ); |
|
156 |
+ |
} |
|
157 |
+ |
// Windows path w/ DriveIndicator which 'might' actually be relative to the given DriveIndicator |
|
158 |
+ |
if ( (path = removeFromFront( zDriveIndicator, path )).length() == 0 ) // Should NOT be possible! |
|
159 |
+ |
{ |
|
160 |
+ |
path = "."; |
|
161 |
+ |
} |
|
162 |
+ |
if ( (path.charAt( 0 ) != pFileSystem.separatorChar()) && !path.startsWith( "." ) ) |
|
163 |
+ |
{ |
|
164 |
+ |
path = "." + pFileSystem.separatorChar() + path; |
|
165 |
+ |
} |
|
166 |
+ |
return canonicalizeAbsoluteNormalizedPath( pFileSystem, zDriveIndicator + path ); |
127 |
167 |
|
} |
128 |
168 |
|
|
129 |
|
- |
private static boolean hasWindowsDriveLetter( IFileSystem pFileSystem, String path ) |
|
169 |
+ |
private static String canonicalizeAbsoluteNormalizedPath( IFileSystem pFileSystem, String path ) |
|
170 |
+ |
throws IOException |
130 |
171 |
|
{ |
131 |
|
- |
return pFileSystem.isWindows() && (path.length() > 1) && (path.charAt( 1 ) == ':'); |
|
172 |
+ |
String origPath = path; |
|
173 |
+ |
if ( !pFileSystem.exists( origPath ) ) |
|
174 |
+ |
{ |
|
175 |
+ |
String zEnd = ""; |
|
176 |
+ |
for ( int at; -1 != (at = path.lastIndexOf( pFileSystem.separatorChar() )); ) |
|
177 |
+ |
{ |
|
178 |
+ |
zEnd = path.substring( at ) + zEnd; |
|
179 |
+ |
if ( pFileSystem.exists( path = path.substring( 0, at ) ) ) |
|
180 |
+ |
{ |
|
181 |
+ |
return pFileSystem.canonicalizeNormalizedExisting( path ) + zEnd; |
|
182 |
+ |
} |
|
183 |
+ |
} |
|
184 |
+ |
} |
|
185 |
+ |
return pFileSystem.canonicalizeNormalizedExisting( origPath ); |
132 |
186 |
|
} |
133 |
187 |
|
} |