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.local;
018:
019: import org.apache.commons.vfs.FileName;
020: import org.apache.commons.vfs.FileSystemException;
021: import org.apache.commons.vfs.FileType;
022:
023: /**
024: * A parser for Windows file names.
025: *
026: * @author <a href="mailto:adammurdoch@apache.org">Adam Murdoch</a>
027: * @version $Revision: 480428 $ $Date: 2006-11-28 22:15:24 -0800 (Tue, 28 Nov 2006) $
028: */
029: public class WindowsFileNameParser extends LocalFileNameParser {
030: /**
031: * Pops the root prefix off a URI, which has had the scheme removed.
032: */
033: protected String extractRootPrefix(final String uri,
034: final StringBuffer name) throws FileSystemException {
035: return extractWindowsRootPrefix(uri, name);
036: }
037:
038: protected FileName createFileName(String scheme,
039: final String rootFile, final String path,
040: final FileType type) {
041: return new WindowsFileName(scheme, rootFile, path, type);
042: }
043:
044: /**
045: * Extracts a Windows root prefix from a name.
046: */
047: private String extractWindowsRootPrefix(final String uri,
048: final StringBuffer name) throws FileSystemException {
049: // Looking for:
050: // ('/'){0, 3} <letter> ':' '/'
051: // ['/'] '//' <name> '/' <name> ( '/' | <end> )
052:
053: // Skip over first 4 (unc) leading '/' chars
054: int startPos = 0;
055: int maxlen = Math.min(4, name.length());
056: for (; startPos < maxlen && name.charAt(startPos) == '/'; startPos++) {
057: }
058: if (startPos == maxlen && name.length() > startPos
059: && name.charAt(startPos + 1) == '/') {
060: // Too many '/'
061: throw new FileSystemException(
062: "vfs.provider.local/not-absolute-file-name.error",
063: uri);
064: }
065: name.delete(0, startPos);
066:
067: // Look for drive name
068: String driveName = extractDrivePrefix(name);
069: if (driveName != null) {
070: return driveName;
071: }
072:
073: // Look for UNC name
074: if (startPos < 2) {
075: throw new FileSystemException(
076: "vfs.provider.local/not-absolute-file-name.error",
077: uri);
078: }
079:
080: return "//" + extractUNCPrefix(uri, name);
081: }
082:
083: /**
084: * Extracts a drive prefix from a path. Leading '/' chars have been removed.
085: */
086: private String extractDrivePrefix(final StringBuffer name) {
087: // Looking for <letter> ':' '/'
088: if (name.length() < 3) {
089: // Too short
090: return null;
091: }
092: char ch = name.charAt(0);
093: if (ch == '/' || ch == ':') {
094: // Missing drive letter
095: return null;
096: }
097: if (name.charAt(1) != ':') {
098: // Missing ':'
099: return null;
100: }
101: if (name.charAt(2) != '/') {
102: // Missing separator
103: return null;
104: }
105:
106: String prefix = name.substring(0, 2);
107: name.delete(0, 2);
108:
109: return prefix.intern();
110: }
111:
112: /**
113: * Extracts a UNC name from a path. Leading '/' chars have been removed.
114: */
115: private String extractUNCPrefix(final String uri,
116: final StringBuffer name) throws FileSystemException {
117: // Looking for <name> '/' <name> ( '/' | <end> )
118:
119: // Look for first separator
120: int maxpos = name.length();
121: int pos = 0;
122: for (; pos < maxpos && name.charAt(pos) != '/'; pos++) {
123: }
124: pos++;
125: if (pos >= maxpos) {
126: throw new FileSystemException(
127: "vfs.provider.local/missing-share-name.error", uri);
128: }
129:
130: // Now have <name> '/'
131: int startShareName = pos;
132: for (; pos < maxpos && name.charAt(pos) != '/'; pos++) {
133: }
134: if (pos == startShareName) {
135: throw new FileSystemException(
136: "vfs.provider.local/missing-share-name.error", uri);
137: }
138:
139: // Now have <name> '/' <name> ( '/' | <end> )
140: String prefix = name.substring(0, pos);
141: name.delete(0, pos);
142: return prefix;
143: }
144: }
|