1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.vfs.provider;
18
19 import org.apache.commons.vfs.FileName;
20 import org.apache.commons.vfs.FileSystemException;
21 import org.apache.commons.vfs.FileType;
22
23 /***
24 * Implementation for layered filesystems.
25 * <p/>
26 * Additionally encodes the '!' character.
27 */
28 public class LayeredFileNameParser extends AbstractFileNameParser
29 {
30 private final static LayeredFileNameParser INSTANCE = new LayeredFileNameParser();
31
32 public static LayeredFileNameParser getInstance()
33 {
34 return INSTANCE;
35 }
36
37 public boolean encodeCharacter(char ch)
38 {
39 return super.encodeCharacter(ch) || ch == '!';
40 }
41
42 public FileName parseUri(final VfsComponentContext context, FileName base, final String filename) throws FileSystemException
43 {
44 final StringBuffer name = new StringBuffer();
45
46
47 final String scheme = UriParser.extractScheme(filename, name);
48
49
50 final String rootUriName = extractRootName(name);
51 FileName rootUri = null;
52 if (rootUriName != null)
53 {
54 rootUri = context.parseURI(rootUriName);
55 }
56
57
58 UriParser.canonicalizePath(name, 0, name.length(), this);
59 UriParser.fixSeparators(name);
60 FileType fileType = UriParser.normalisePath(name);
61 final String path = name.toString();
62
63 return new LayeredFileName(scheme, rootUri, path, fileType);
64 }
65
66 /***
67 * Pops the root prefix off a URI, which has had the scheme removed.
68 */
69 protected String extractRootName(final StringBuffer uri)
70 throws FileSystemException
71 {
72
73 int maxlen = uri.length();
74 int pos = maxlen - 1;
75 for (; pos > 0 && uri.charAt(pos) != '!'; pos--)
76 {
77 }
78
79 if (pos == 0 && uri.charAt(pos) != '!')
80 {
81
82
83 pos = maxlen;
84 }
85
86
87 String prefix = uri.substring(0, pos);
88 if (pos < maxlen)
89 {
90 uri.delete(0, pos + 1);
91 }
92 else
93 {
94 uri.setLength(0);
95 }
96
97 return prefix;
98 }
99
100 }