1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35 package org.exolab.castor.net.util;
36
37
38 import java.io.*;
39 import java.net.URL;
40 import java.net.MalformedURLException;
41 import java.util.Stack;
42 import java.util.StringTokenizer;
43
44 import org.apache.commons.lang3.StringUtils;
45
46
47
48
49
50
51 public class URIUtils {
52
53
54
55
56 private static final String FILE_PROTOCOL_PREFIX = "file:///";
57
58
59
60
61 private static final char HREF_PATH_SEP = '/';
62
63
64
65
66 private static final String URL_PATH_SEP_STR = "/";
67
68
69
70
71 private static final String CURRENT_DIR_OP = ".";
72
73
74
75
76 private static final String PARENT_DIR_OP = "..";
77
78
79
80
81
82
83
84
85
86
87
88 public static InputStream getInputStream(String href, String documentBase)
89 throws java.io.FileNotFoundException, java.io.IOException {
90
91
92 URL url = null;
93 try {
94 url = new URL(href);
95 return url.openStream();
96 } catch (MalformedURLException muex) {
97 }
98
99
100 String xHref = null;
101 if ((documentBase != null) && (documentBase.length() > 0)) {
102 int idx = documentBase.lastIndexOf(HREF_PATH_SEP);
103 if (idx == (documentBase.length() - 1))
104 xHref = documentBase + href;
105 else
106 xHref = documentBase + HREF_PATH_SEP + href;
107 } else
108 xHref = href;
109
110
111 try {
112 url = new URL(xHref);
113 return url.openStream();
114 } catch (MalformedURLException muex) {
115 }
116
117
118 File iFile = new File(href);
119 if (iFile.isAbsolute())
120 return new FileInputStream(iFile);
121
122 iFile = new File(xHref);
123 return new FileInputStream(iFile);
124
125 }
126
127
128
129
130
131
132
133
134
135
136 public static Reader getReader(String href, String documentBase)
137 throws java.io.FileNotFoundException, java.io.IOException {
138 InputStream is = getInputStream(href, documentBase);
139 return new InputStreamReader(is);
140 }
141
142
143
144
145
146
147 public static String getDocumentBase(String href) {
148
149 String docBase = "";
150
151 if (href == null)
152 return docBase;
153
154 int idx = -1;
155
156 try {
157
158
159 new URL(href);
160 idx = href.lastIndexOf(HREF_PATH_SEP);
161 } catch (MalformedURLException muex) {
162
163
164 int idx2 = href.lastIndexOf(HREF_PATH_SEP);
165 idx = href.lastIndexOf(File.separator);
166 if (idx2 > idx)
167 idx = idx2;
168 }
169
170 if (idx >= 0)
171 docBase = href.substring(0, idx);
172
173 return docBase;
174 }
175
176
177
178
179
180
181 public static String getRelativeURI(String href) {
182
183 if (href == null)
184 return href;
185
186 int idx = -1;
187
188 try {
189
190
191 new URL(href);
192 idx = href.lastIndexOf(HREF_PATH_SEP);
193 } catch (MalformedURLException muex) {
194
195
196 int idx2 = href.lastIndexOf(HREF_PATH_SEP);
197 idx = href.lastIndexOf(File.separator);
198 if (idx2 > idx)
199 idx = idx2;
200 }
201
202 if (idx >= 0)
203 return href.substring(idx + 1);
204
205 return href;
206 }
207
208
209
210
211
212
213
214 public static String normalize(String absoluteURL) throws MalformedURLException {
215 if (absoluteURL == null)
216 return absoluteURL;
217 if (absoluteURL.indexOf('.') < 0)
218 return absoluteURL;
219
220
221
222
223 Stack tokens = new Stack();
224 StringTokenizer st = new StringTokenizer(absoluteURL, URL_PATH_SEP_STR, true);
225 String last = null;
226 while (st.hasMoreTokens()) {
227 String token = st.nextToken();
228 if (URL_PATH_SEP_STR.equals(token)) {
229 if (URL_PATH_SEP_STR.equals(last)) {
230 tokens.push("");
231 }
232 } else if (PARENT_DIR_OP.equals(token)) {
233 if (tokens.empty()) {
234
235 throw new MalformedURLException("invalid absolute URL: " + absoluteURL);
236 }
237 tokens.pop();
238 } else {
239 if (!CURRENT_DIR_OP.equals(token)) {
240 tokens.push(token);
241 }
242 }
243 last = token;
244 }
245
246
247 return StringUtils.join(tokens, HREF_PATH_SEP);
248 }
249
250
251
252
253
254 public static String resolveAsString(String href, String documentBase) {
255
256 try {
257
258
259 new URL(href);
260 return href;
261 } catch (MalformedURLException muex) {
262 }
263
264
265
266 String absolute = null;
267 if ((documentBase != null) && (documentBase.length() > 0)) {
268 int idx = documentBase.lastIndexOf(HREF_PATH_SEP);
269 if (idx == (documentBase.length() - 1))
270 absolute = documentBase + href;
271 else
272 absolute = documentBase + HREF_PATH_SEP + href;
273
274
275 } else
276 absolute = href;
277
278
279 try {
280
281
282
283 if (absolute.indexOf("./") >= 0) {
284
285 absolute = normalize(absolute);
286 }
287 new URL(absolute);
288 return absolute;
289 } catch (MalformedURLException muex) {
290
291 int idx = absolute.indexOf(':');
292 if (idx >= 0) {
293 String scheme = absolute.substring(0, idx);
294
295 String error = "unknown protocol: " + scheme;
296 if (error.equals(muex.getMessage())) {
297 return absolute;
298 }
299 }
300
301 }
302
303
304
305 String fileURL = absolute;
306 File iFile = new File(href);
307 boolean exists = iFile.exists();
308 fileURL = createFileURL(iFile.getAbsolutePath());
309 if (!iFile.isAbsolute()) {
310 iFile = new File(absolute);
311 if (iFile.exists() || (!exists)) {
312 fileURL = createFileURL(iFile.getAbsolutePath());
313 }
314 }
315
316
317 try {
318
319
320 new URL(fileURL);
321 return fileURL;
322 } catch (MalformedURLException muex) {
323 }
324
325
326
327
328
329 return absolute;
330 }
331
332
333
334
335
336
337
338 private static String createFileURL(String filename) {
339
340 if (filename == null)
341 return FILE_PROTOCOL_PREFIX;
342 int size = filename.length() + FILE_PROTOCOL_PREFIX.length();
343 StringBuilder sb = new StringBuilder(size);
344 sb.append(FILE_PROTOCOL_PREFIX);
345 char[] chars = filename.toCharArray();
346 for (char ch : chars) {
347 if ('\\' == ch) {
348 sb.append(HREF_PATH_SEP);
349 } else {
350 sb.append(ch);
351 }
352 }
353 return sb.toString();
354 }
355
356
357 }