001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: package org.apache.commons.vfs.provider.url;
018:
019: import org.apache.commons.vfs.FileName;
020: import org.apache.commons.vfs.FileSystemException;
021: import org.apache.commons.vfs.provider.AbstractFileNameParser;
022: import org.apache.commons.vfs.provider.URLFileName;
023: import org.apache.commons.vfs.provider.URLFileNameParser;
024: import org.apache.commons.vfs.provider.VfsComponentContext;
025: import org.apache.commons.vfs.provider.local.GenericFileNameParser;
026:
027: /**
028: * Implementation for any java.net.url based filesystem.<br />
029: * Composite of URLFilenameParser and GenericFilenameParser
030: *
031: * @author imario@apache.org
032: * @version $Revision: 480428 $ $Date: 2006-11-28 22:15:24 -0800 (Tue, 28 Nov 2006) $
033: */
034: public class UrlFileNameParser extends AbstractFileNameParser {
035: private URLFileNameParser url = new URLFileNameParser(80);
036: private GenericFileNameParser generic = new GenericFileNameParser();
037:
038: public UrlFileNameParser() {
039: super ();
040: }
041:
042: public boolean encodeCharacter(char ch) {
043: return super .encodeCharacter(ch) || ch == '?';
044: }
045:
046: public FileName parseUri(final VfsComponentContext context,
047: final FileName base, final String filename)
048: throws FileSystemException {
049: if (isUrlBased(base, filename)) {
050: return url.parseUri(context, base, filename);
051: }
052:
053: return generic.parseUri(context, base, filename);
054: }
055:
056: /**
057: * Guess is the given filename is a url with host or not. VFS treats such urls differently.<br />
058: * A filename is url-based if the base is a <code>URLFileName</code> or there are only 2 slashes
059: * after the scheme.<br/>
060: * e.g: http://host/path, file:/path/to/file, file:///path/to/file
061: *
062: */
063: protected boolean isUrlBased(final FileName base,
064: final String filename) {
065: if (base instanceof URLFileName) {
066: return true;
067: }
068:
069: int nuofSlash = countSlashes(filename);
070: return nuofSlash == 2;
071: }
072:
073: /**
074: * This method counts the slashes after the scheme.
075: *
076: * @param filename
077: * @return nuof slashes
078: */
079: protected int countSlashes(final String filename) {
080: int state = 0;
081: int nuofSlash = 0;
082: for (int pos = 0; pos < filename.length(); pos++) {
083: char c = filename.charAt(pos);
084: if (state == 0) {
085: if (c >= 'a' && c <= 'z') {
086: continue;
087: }
088: if (c == ':') {
089: state++;
090: continue;
091: }
092: } else if (state == 1) {
093: if (c == '/') {
094: nuofSlash++;
095: } else {
096: return nuofSlash;
097: }
098: }
099: }
100: return nuofSlash;
101: }
102: }
|