44 |
import java.net.URLStreamHandler; |
import java.net.URLStreamHandler; |
45 |
import java.net.URLConnection; |
import java.net.URLConnection; |
46 |
import java.io.IOException; |
import java.io.IOException; |
47 |
|
import gnu.java.io.PlatformHelper; |
48 |
|
|
49 |
/** |
/** |
50 |
* This is the protocol handler for the "file" protocol. |
* This is the protocol handler for the "file" protocol. |
78 |
return (new gnu.java.net.protocol.file.FileURLConnection(url)); |
return (new gnu.java.net.protocol.file.FileURLConnection(url)); |
79 |
} |
} |
80 |
|
|
81 |
|
/** |
82 |
|
* This method overrides URLStreamHandler's for parsing url of protocol "file" |
83 |
|
* |
84 |
|
* @param url The URL object in which to store the results |
85 |
|
* @param url_string The String-ized URL to parse |
86 |
|
* @param start The position in the string to start scanning from |
87 |
|
* @param end The position in the string to stop scanning |
88 |
|
*/ |
89 |
|
protected void |
90 |
|
parseURL(URL url, String url_string, int start, int end) |
91 |
|
{ |
92 |
|
// This method does not throw an exception or return a value. Thus our |
93 |
|
// strategy when we encounter an error in parsing is to return without |
94 |
|
// doing anything. |
95 |
|
|
96 |
|
// Bunches of things should be true. Make sure. |
97 |
|
if (end < start) |
98 |
|
return; |
99 |
|
if (end - start < 2) |
100 |
|
return; |
101 |
|
if (start > url_string.length()) |
102 |
|
return; |
103 |
|
if (end > url_string.length()) |
104 |
|
end = url_string.length(); // This should be safe |
105 |
|
|
106 |
|
// Turn end into an offset from the end of the string instead of |
107 |
|
// the beginning |
108 |
|
end = url_string.length() - end; |
109 |
|
|
110 |
|
// Skip remains of protocol |
111 |
|
url_string = url_string.substring(start); |
112 |
|
|
113 |
|
if ( !url.getProtocol().equals("file") ) |
114 |
|
return; |
115 |
|
|
116 |
|
// Normalize the file separator |
117 |
|
url_string = url_string.replace(System.getProperty("file.separator").charAt(0), '/'); |
118 |
|
|
119 |
|
// Deal with the case: file:///d|/dir/dir/file and file:///d%7C/dir/dir/file |
120 |
|
url_string = url_string.replace('|', ':'); |
121 |
|
int i; |
122 |
|
if ((i = url_string.toUpperCase().indexOf("%7C")) >= 0) |
123 |
|
url_string = url_string.substring(0, i) + ":" + url_string.substring(i+3); |
124 |
|
|
125 |
|
boolean needContext = url.getFile() != null; |
126 |
|
// Skip the leading "//" |
127 |
|
if (url_string.startsWith("//")){ |
128 |
|
url_string = url_string.substring(2); |
129 |
|
needContext = false; |
130 |
|
} |
131 |
|
|
132 |
|
// Declare some variables |
133 |
|
String host = null; |
134 |
|
int port = -1; |
135 |
|
String file = null; |
136 |
|
String anchor = null; |
137 |
|
String prefix = "/"; //root path prefix of a file: could be "/", and for some windows file: "drive:/" |
138 |
|
|
139 |
|
if (!needContext){ |
140 |
|
boolean hostpart = true; //whether host part presents |
141 |
|
|
142 |
|
// Deal with the UNC case: //server/file |
143 |
|
if ( url_string.startsWith("//") ){ |
144 |
|
hostpart = true; |
145 |
|
url_string = url_string.substring(2); |
146 |
|
} |
147 |
|
else { |
148 |
|
// If encounter another "/", it's end of a null host part or beginning of root path |
149 |
|
if ( url_string.startsWith("/") ){ |
150 |
|
hostpart = false; |
151 |
|
url_string = url_string.substring(1); |
152 |
|
} |
153 |
|
} |
154 |
|
|
155 |
|
// If another "/" or "drive:/" or "drive:\\" encounters, |
156 |
|
if ( (i = PlatformHelper.beginWithRootPathPrefix(url_string)) > 0) { |
157 |
|
hostpart = false; |
158 |
|
// Skip root path prefix |
159 |
|
prefix = url_string.substring(0, i); |
160 |
|
url_string = url_string.substring(i); |
161 |
|
} |
162 |
|
|
163 |
|
if (hostpart){ |
164 |
|
// Process host and port |
165 |
|
int slash_index = url_string.indexOf("/"); |
166 |
|
int colon_index = url_string.indexOf(":"); |
167 |
|
|
168 |
|
if (slash_index > (url_string.length() - end)) |
169 |
|
return; |
170 |
|
else if (slash_index == -1) |
171 |
|
slash_index = url_string.length() - end; |
172 |
|
|
173 |
|
if ((colon_index == -1) || (colon_index > slash_index)) { |
174 |
|
host = url_string.substring(0, slash_index); |
175 |
|
} |
176 |
|
else { |
177 |
|
host = url_string.substring(0, colon_index); |
178 |
|
|
179 |
|
String port_str = url_string.substring(colon_index + 1, slash_index); |
180 |
|
try { |
181 |
|
port = Integer.parseInt(port_str); |
182 |
|
} |
183 |
|
catch (NumberFormatException e) { |
184 |
|
return; |
185 |
|
} |
186 |
|
} |
187 |
|
if (slash_index < (url_string.length() - 1)) |
188 |
|
url_string = url_string.substring(slash_index + 1); |
189 |
|
else |
190 |
|
url_string = ""; |
191 |
|
} |
192 |
|
} |
193 |
|
|
194 |
|
// Process file and anchor |
195 |
|
if (needContext){ |
196 |
|
host = url.getHost(); |
197 |
|
port = url.getPort(); |
198 |
|
if ( (i = PlatformHelper.beginWithRootPathPrefix(url_string)) > 0){ //url string is an absolute path |
199 |
|
file = url.getFile(); |
200 |
|
int j = PlatformHelper.beginWithRootPathPrefix(file); |
201 |
|
if (j >= i) |
202 |
|
file = file.substring(0, j) + url_string.substring(i); |
203 |
|
else |
204 |
|
file = url_string; |
205 |
|
}else{ |
206 |
|
file = url.getFile(); |
207 |
|
/* |
208 |
|
// Is the following necessary? |
209 |
|
java.io.File f = new java.io.File(file); |
210 |
|
if(f.isDirectory() && !PlatformHelper.endWithSeparator(file)){ |
211 |
|
file += "/"; |
212 |
|
} |
213 |
|
*/ |
214 |
|
|
215 |
|
int idx = file.lastIndexOf("/"); |
216 |
|
if (idx == -1) //context path is weird |
217 |
|
file = "/" + url_string; |
218 |
|
else if (idx == (file.length() - 1)) |
219 |
|
//just concatenate two parts |
220 |
|
file = file + url_string; |
221 |
|
else |
222 |
|
file = file.substring(0, idx + 1) + url_string; |
223 |
|
} |
224 |
|
}else |
225 |
|
file = prefix + url_string; |
226 |
|
|
227 |
|
if (end == 0) { |
228 |
|
anchor = null; |
229 |
|
} else { |
230 |
|
// Only set anchor if end char is a '#'. Otherwise assume we're |
231 |
|
// just supposed to stop scanning for some reason |
232 |
|
if (file.charAt(file.length() - end) == '#'){ |
233 |
|
int len = file.length(); |
234 |
|
anchor = file.substring( len - end + 1, len); |
235 |
|
file = file.substring(0, len - end); |
236 |
|
}else |
237 |
|
anchor = null; |
238 |
|
} |
239 |
|
file = PlatformHelper.toCanonicalForm(file, '/'); |
240 |
|
|
241 |
|
// Now set the values |
242 |
|
setURL(url, url.getProtocol(), host, port, file, anchor); |
243 |
|
} |
244 |
|
|
245 |
} // class Handler |
} // class Handler |
246 |
|
|