001: /*
002: * The Apache Software License, Version 1.1
003: *
004: * Copyright (c) 2000,2002 The Apache Software Foundation. All rights
005: * reserved.
006: *
007: * Redistribution and use in source and binary forms, with or without
008: * modification, are permitted provided that the following conditions
009: * are met:
010: *
011: * 1. Redistributions of source code must retain the above copyright
012: * notice, this list of conditions and the following disclaimer.
013: *
014: * 2. Redistributions in binary form must reproduce the above copyright
015: * notice, this list of conditions and the following disclaimer in
016: * the documentation and/or other materials provided with the
017: * distribution.
018: *
019: * 3. The end-user documentation included with the redistribution, if
020: * any, must include the following acknowlegement:
021: * "This product includes software developed by the
022: * Apache Software Foundation (http://www.apache.org/)."
023: * Alternately, this acknowlegement may appear in the software itself,
024: * if and wherever such third-party acknowlegements normally appear.
025: *
026: * 4. The names "Ant" and "Apache Software
027: * Foundation" must not be used to endorse or promote products derived
028: * from this software without prior written permission. For written
029: * permission, please contact apache@apache.org.
030: *
031: * 5. Products derived from this software may not be called "Apache"
032: * nor may "Apache" appear in their names without prior written
033: * permission of the Apache Group.
034: *
035: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
036: * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
037: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
038: * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
039: * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
040: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
041: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
042: * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
043: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
044: * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
045: * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
046: * SUCH DAMAGE.
047: * ====================================================================
048: *
049: * This software consists of voluntary contributions made by many
050: * individuals on behalf of the Apache Software Foundation. For more
051: * information on the Apache Software Foundation, please see
052: * <http://www.apache.org/>.
053: */
054: package org.acm.seguin.project;
055:
056: import java.util.NoSuchElementException;
057: import java.util.StringTokenizer;
058: import java.io.File;
059:
060: /**
061: * A Path tokenizer takes a path and returns the components that make up
062: * that path.
063: *
064: * The path can use path separators of either ':' or ';' and file separators
065: * of either '/' or '\'.
066: *
067: * @author Conor MacNeill
068: * @author <a href="mailto:jtulley@novell.com">Jeff Tulley</a>
069: * @author Mike Atkinson
070: * @version $Id: PathTokenizer.java,v 1.2 2003/09/04 19:47:13 mikeatkinson Exp $
071: * @since 2.8.01
072: */
073: public class PathTokenizer {
074: /**
075: * A tokenizer to break the string up based on the ':' or ';' separators.
076: */
077: private StringTokenizer tokenizer;
078:
079: /**
080: * A String which stores any path components which have been read ahead
081: * due to DOS filesystem compensation.
082: */
083: private String lookahead = null;
084:
085: /**
086: * Flag to indicate whether or not we are running on a platform with a
087: * DOS style filesystem
088: */
089: private boolean dosStyleFilesystem;
090:
091: /**
092: * Constructs a path tokenizer for the specified path.
093: *
094: * @param path The path to tokenize. Must not be <code>null</code>.
095: */
096: public PathTokenizer(String path) {
097: // on Windows and Unix, we can ignore delimiters and still have
098: // enough information to tokenize correctly.
099: tokenizer = new StringTokenizer(path, ":;", false);
100: dosStyleFilesystem = File.pathSeparatorChar == ';';
101: }
102:
103: /**
104: * Tests if there are more path elements available from this tokenizer's
105: * path. If this method returns <code>true</code>, then a subsequent call
106: * to nextToken will successfully return a token.
107: *
108: * @return <code>true</code> if and only if there is at least one token
109: * in the string after the current position; <code>false</code> otherwise.
110: */
111: public boolean hasMoreTokens() {
112: if (lookahead != null) {
113: return true;
114: }
115:
116: return tokenizer.hasMoreTokens();
117: }
118:
119: /**
120: * Returns the next path element from this tokenizer.
121: *
122: * @return the next path element from this tokenizer.
123: *
124: * @exception NoSuchElementException if there are no more elements in this
125: * tokenizer's path.
126: */
127: public String nextToken() throws NoSuchElementException {
128: String token = null;
129: if (lookahead != null) {
130: token = lookahead;
131: lookahead = null;
132: } else {
133: token = tokenizer.nextToken().trim();
134: }
135:
136: if (token.length() == 1 && Character.isLetter(token.charAt(0))
137: && dosStyleFilesystem && tokenizer.hasMoreTokens()) {
138: // we are on a dos style system so this path could be a drive
139: // spec. We look at the next token
140: String nextToken = tokenizer.nextToken().trim();
141: if (nextToken.startsWith("\\") || nextToken.startsWith("/")) {
142: // we know we are on a DOS style platform and the next path
143: // starts with a slash or backslash, so we know this is a
144: // drive spec
145: token += ":" + nextToken;
146: } else {
147: // store the token just read for next time
148: lookahead = nextToken;
149: }
150: }
151: return token;
152: }
153: }
|