100dc7bdcf1df9e86789d963984dfc6912a8854c6chrismair/*
200dc7bdcf1df9e86789d963984dfc6912a8854c6chrismair * Copyright 2008 the original author or authors.
300dc7bdcf1df9e86789d963984dfc6912a8854c6chrismair *
400dc7bdcf1df9e86789d963984dfc6912a8854c6chrismair * Licensed under the Apache License, Version 2.0 (the "License");
500dc7bdcf1df9e86789d963984dfc6912a8854c6chrismair * you may not use this file except in compliance with the License.
600dc7bdcf1df9e86789d963984dfc6912a8854c6chrismair * You may obtain a copy of the License at
700dc7bdcf1df9e86789d963984dfc6912a8854c6chrismair *
800dc7bdcf1df9e86789d963984dfc6912a8854c6chrismair *      http://www.apache.org/licenses/LICENSE-2.0
900dc7bdcf1df9e86789d963984dfc6912a8854c6chrismair *
1000dc7bdcf1df9e86789d963984dfc6912a8854c6chrismair * Unless required by applicable law or agreed to in writing, software
1100dc7bdcf1df9e86789d963984dfc6912a8854c6chrismair * distributed under the License is distributed on an "AS IS" BASIS,
1200dc7bdcf1df9e86789d963984dfc6912a8854c6chrismair * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1300dc7bdcf1df9e86789d963984dfc6912a8854c6chrismair * See the License for the specific language governing permissions and
1400dc7bdcf1df9e86789d963984dfc6912a8854c6chrismair * limitations under the License.
1500dc7bdcf1df9e86789d963984dfc6912a8854c6chrismair */
1600dc7bdcf1df9e86789d963984dfc6912a8854c6chrismairpackage org.mockftpserver.fake.filesystem;
1700dc7bdcf1df9e86789d963984dfc6912a8854c6chrismair
1800dc7bdcf1df9e86789d963984dfc6912a8854c6chrismairimport org.mockftpserver.core.util.Assert;
1900dc7bdcf1df9e86789d963984dfc6912a8854c6chrismair
2000dc7bdcf1df9e86789d963984dfc6912a8854c6chrismair/**
2100dc7bdcf1df9e86789d963984dfc6912a8854c6chrismair * Implementation of the {@link FileSystem} interface that simulates a Unix
2200dc7bdcf1df9e86789d963984dfc6912a8854c6chrismair * file system. The rules for file and directory names include:
2300dc7bdcf1df9e86789d963984dfc6912a8854c6chrismair * <ul>
2400dc7bdcf1df9e86789d963984dfc6912a8854c6chrismair * <li>Filenames are case-sensitive</li>
2500dc7bdcf1df9e86789d963984dfc6912a8854c6chrismair * <li>Forward slashes (/) are the only valid path separators</li>
2600dc7bdcf1df9e86789d963984dfc6912a8854c6chrismair * </ul>
2700dc7bdcf1df9e86789d963984dfc6912a8854c6chrismair * <p/>
2800dc7bdcf1df9e86789d963984dfc6912a8854c6chrismair * The <code>directoryListingFormatter</code> property is automatically initialized to an instance
2900dc7bdcf1df9e86789d963984dfc6912a8854c6chrismair * of {@link UnixDirectoryListingFormatter}.
3000dc7bdcf1df9e86789d963984dfc6912a8854c6chrismair *
3100dc7bdcf1df9e86789d963984dfc6912a8854c6chrismair * @author Chris Mair
3200dc7bdcf1df9e86789d963984dfc6912a8854c6chrismair * @version $Revision$ - $Date$
3300dc7bdcf1df9e86789d963984dfc6912a8854c6chrismair */
3400dc7bdcf1df9e86789d963984dfc6912a8854c6chrismairpublic class UnixFakeFileSystem extends AbstractFakeFileSystem {
3500dc7bdcf1df9e86789d963984dfc6912a8854c6chrismair
3600dc7bdcf1df9e86789d963984dfc6912a8854c6chrismair    public static final char SEPARATOR = '/';
3700dc7bdcf1df9e86789d963984dfc6912a8854c6chrismair
3800dc7bdcf1df9e86789d963984dfc6912a8854c6chrismair    /**
3900dc7bdcf1df9e86789d963984dfc6912a8854c6chrismair     * Construct a new instance and initialize the directoryListingFormatter to a UnixDirectoryListingFormatter.
4000dc7bdcf1df9e86789d963984dfc6912a8854c6chrismair     */
4100dc7bdcf1df9e86789d963984dfc6912a8854c6chrismair    public UnixFakeFileSystem() {
4200dc7bdcf1df9e86789d963984dfc6912a8854c6chrismair        this.setDirectoryListingFormatter(new UnixDirectoryListingFormatter());
4300dc7bdcf1df9e86789d963984dfc6912a8854c6chrismair    }
4400dc7bdcf1df9e86789d963984dfc6912a8854c6chrismair
4500dc7bdcf1df9e86789d963984dfc6912a8854c6chrismair    //-------------------------------------------------------------------------
4600dc7bdcf1df9e86789d963984dfc6912a8854c6chrismair    // Abstract Method Implementations
4700dc7bdcf1df9e86789d963984dfc6912a8854c6chrismair    //-------------------------------------------------------------------------
4800dc7bdcf1df9e86789d963984dfc6912a8854c6chrismair
4900dc7bdcf1df9e86789d963984dfc6912a8854c6chrismair    protected char getSeparatorChar() {
5000dc7bdcf1df9e86789d963984dfc6912a8854c6chrismair        return SEPARATOR;
5100dc7bdcf1df9e86789d963984dfc6912a8854c6chrismair    }
5200dc7bdcf1df9e86789d963984dfc6912a8854c6chrismair
5300dc7bdcf1df9e86789d963984dfc6912a8854c6chrismair    /**
5400dc7bdcf1df9e86789d963984dfc6912a8854c6chrismair     * Return true if the specified path designates a valid (absolute) file path. For Unix,
5500dc7bdcf1df9e86789d963984dfc6912a8854c6chrismair     * a path is valid if it starts with the '/' character, followed by zero or more names
5600dc7bdcf1df9e86789d963984dfc6912a8854c6chrismair     * (a sequence of any characters except '/'), delimited by '/'. The path may optionally
5700dc7bdcf1df9e86789d963984dfc6912a8854c6chrismair     * contain a terminating '/'.
5800dc7bdcf1df9e86789d963984dfc6912a8854c6chrismair     *
5900dc7bdcf1df9e86789d963984dfc6912a8854c6chrismair     * @param path - the path
6000dc7bdcf1df9e86789d963984dfc6912a8854c6chrismair     * @return true if path is valid, false otherwise
6100dc7bdcf1df9e86789d963984dfc6912a8854c6chrismair     * @throws AssertionError - if path is null
6200dc7bdcf1df9e86789d963984dfc6912a8854c6chrismair     */
6300dc7bdcf1df9e86789d963984dfc6912a8854c6chrismair    protected boolean isValidName(String path) {
6400dc7bdcf1df9e86789d963984dfc6912a8854c6chrismair        Assert.notNull(path, "path");
6500dc7bdcf1df9e86789d963984dfc6912a8854c6chrismair        // Any character but '/'
6600dc7bdcf1df9e86789d963984dfc6912a8854c6chrismair        return path.matches("\\/|(\\/[^\\/]+\\/?)+");
6700dc7bdcf1df9e86789d963984dfc6912a8854c6chrismair
6800dc7bdcf1df9e86789d963984dfc6912a8854c6chrismair    }
6900dc7bdcf1df9e86789d963984dfc6912a8854c6chrismair
7000dc7bdcf1df9e86789d963984dfc6912a8854c6chrismair    /**
7100dc7bdcf1df9e86789d963984dfc6912a8854c6chrismair     * Return true if the specified char is a separator character ('\' or '/')
7200dc7bdcf1df9e86789d963984dfc6912a8854c6chrismair     *
7300dc7bdcf1df9e86789d963984dfc6912a8854c6chrismair     * @param c - the character to test
7400dc7bdcf1df9e86789d963984dfc6912a8854c6chrismair     * @return true if the specified char is a separator character ('\' or '/')
7500dc7bdcf1df9e86789d963984dfc6912a8854c6chrismair     */
7600dc7bdcf1df9e86789d963984dfc6912a8854c6chrismair    protected boolean isSeparator(char c) {
7700dc7bdcf1df9e86789d963984dfc6912a8854c6chrismair        return c == SEPARATOR;
7800dc7bdcf1df9e86789d963984dfc6912a8854c6chrismair    }
7900dc7bdcf1df9e86789d963984dfc6912a8854c6chrismair
8000dc7bdcf1df9e86789d963984dfc6912a8854c6chrismair    /**
8100dc7bdcf1df9e86789d963984dfc6912a8854c6chrismair     * @return true if the specified path component is a root for this filesystem
8200dc7bdcf1df9e86789d963984dfc6912a8854c6chrismair     */
8300dc7bdcf1df9e86789d963984dfc6912a8854c6chrismair    protected boolean isRoot(String pathComponent) {
8400dc7bdcf1df9e86789d963984dfc6912a8854c6chrismair        return pathComponent.indexOf(":") != -1;
8500dc7bdcf1df9e86789d963984dfc6912a8854c6chrismair    }
8600dc7bdcf1df9e86789d963984dfc6912a8854c6chrismair
8700dc7bdcf1df9e86789d963984dfc6912a8854c6chrismair}