01: /*
02: * Licensed to the Apache Software Foundation (ASF) under one or more
03: * contributor license agreements. See the NOTICE file distributed with
04: * this work for additional information regarding copyright ownership.
05: * The ASF licenses this file to You under the Apache License, Version 2.0
06: * (the "License"); you may not use this file except in compliance with
07: * the License. You may obtain a copy of the License at
08: *
09: * http://www.apache.org/licenses/LICENSE-2.0
10: *
11: * Unless required by applicable law or agreed to in writing, software
12: * distributed under the License is distributed on an "AS IS" BASIS,
13: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14: * See the License for the specific language governing permissions and
15: * limitations under the License.
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: private final static LayeredFileNameParser INSTANCE = new LayeredFileNameParser();
30:
31: public static LayeredFileNameParser getInstance() {
32: return INSTANCE;
33: }
34:
35: public boolean encodeCharacter(char ch) {
36: return super .encodeCharacter(ch) || ch == '!';
37: }
38:
39: public FileName parseUri(final VfsComponentContext context,
40: FileName base, final String filename)
41: throws FileSystemException {
42: final StringBuffer name = new StringBuffer();
43:
44: // Extract the scheme
45: final String scheme = UriParser.extractScheme(filename, name);
46:
47: // Extract the Layered file URI
48: final String rootUriName = extractRootName(name);
49: FileName rootUri = null;
50: if (rootUriName != null) {
51: rootUri = context.parseURI(rootUriName);
52: }
53:
54: // Decode and normalise the path
55: UriParser.canonicalizePath(name, 0, name.length(), this );
56: UriParser.fixSeparators(name);
57: FileType fileType = UriParser.normalisePath(name);
58: final String path = name.toString();
59:
60: return new LayeredFileName(scheme, rootUri, path, fileType);
61: }
62:
63: /**
64: * Pops the root prefix off a URI, which has had the scheme removed.
65: */
66: protected String extractRootName(final StringBuffer uri)
67: throws FileSystemException {
68: // Looking for <name>!<abspath> (staring at the end)
69: int maxlen = uri.length();
70: int pos = maxlen - 1;
71: for (; pos > 0 && uri.charAt(pos) != '!'; pos--) {
72: }
73:
74: if (pos == 0 && uri.charAt(pos) != '!') {
75: // not ! found, so take the whole path a root
76: // e.g. zip:/my/zip/file.zip
77: pos = maxlen;
78: }
79:
80: // Extract the name
81: String prefix = uri.substring(0, pos);
82: if (pos < maxlen) {
83: uri.delete(0, pos + 1);
84: } else {
85: uri.setLength(0);
86: }
87:
88: return prefix;
89: }
90:
91: }
|