Package org.jboss.aesh.util

Source Code of org.jboss.aesh.util.FileLister

/*
* Copyright 2013 Red Hat, Inc. and/or its affiliates.
*
* Licensed under the Eclipse Public License version 1.0, available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.jboss.aesh.util;

import static org.jboss.aesh.constants.AeshConstants.ESCAPE;
import static org.jboss.aesh.constants.AeshConstants.HOME;
import static org.jboss.aesh.constants.AeshConstants.PARENT;
import static org.jboss.aesh.constants.AeshConstants.STAR;
import static org.jboss.aesh.constants.AeshConstants.WILDCARD;

import java.io.File;
import java.io.FileFilter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import org.jboss.aesh.comparators.PosixFileNameComparator;
import org.jboss.aesh.complete.CompleteOperation;
import org.jboss.aesh.console.Config;
import org.jboss.aesh.filters.Filter;
import org.jboss.aesh.parser.Parser;
import org.jboss.aesh.terminal.TerminalString;

/**
* Helper class to list possible files during a complete operation.
*
* @author <a href="mailto:stale.pedersen@jboss.org">Ståle W. Pedersen</a>
*/
public class FileLister {

    private static final File[] windowsRoots = File.listRoots();

    private String token;
    private File cwd;
    private String rest;
    private String lastDir;
    private FileFilter fileFilter;
    private Comparator fileComparator;

    public FileLister(String token, File cwd) {
        if (token == null)
            throw new IllegalArgumentException("Incoming directory cannot be null");
        if (cwd == null)
            throw new IllegalArgumentException("Current working directory cannot be null");
        this.token = Parser.switchEscapedSpacesToSpacesInWord(token);
        this.cwd = cwd;
        findRestAndLastDir();
        setFileFilter(Filter.ALL);
    }

    public FileLister(String token, File cwd, Comparator comparator) {
        this(token, cwd);
        this.fileComparator = comparator;
    }

    public FileLister(String token, File cwd, Filter filter) {
        this(token, cwd);
        setFileFilter(filter);
    }

    public FileLister(String token, File cwd, Filter filter, Comparator fileComparator) {
        this(token, cwd, filter);
        this.fileComparator = fileComparator;
    }

    public FileLister(String token, File cwd, FileFilter fileFilter) {
        this(token, cwd);
        this.fileFilter = fileFilter;
    }

    public FileLister(String token, File cwd, FileFilter fileFilter, Comparator fileComparator) {
        this(token, cwd, fileFilter);
        this.fileComparator = fileComparator;
    }

    private void setFileFilter(Filter filter) {
        this.fileFilter = filter.getFileFilter();
    }

    /**
     * findMatchingDirectories will try to populate the CompleteOperation object based on it initial params.
     *
     * @param completion
     */
    public void findMatchingDirectories(CompleteOperation completion) {
        completion.doAppendSeparator(false);

        // if token is empty, just list cwd
        if (token.trim().isEmpty()) {
            completion.addCompletionCandidates(listDirectory(cwd, null));
        }
        else if (containStar()) {
        }
        else if (containWildCards()) {
        }
        else if (startWithHome()) {
            if (isHomeAndTokenADirectory()) {
                if (tokenEndsWithSlash()) {
                    completion.addCompletionCandidates(
                        listDirectory(new File(Config.getHomeDir() + token.substring(1)), null));
                }
                else {
                    // completion.addCompletionCandidate(Config.getPathSeparator());
                    List<String> tmpDirs = listDirectory(new File(Config.getHomeDir()), token.substring(2));
                    if (tmpDirs.size() == 1 || endsWithParent()) {
                        completion.addCompletionCandidate(Config.getPathSeparator());
                    }
                    else
                        completion.addCompletionCandidates(tmpDirs);
                }
            }
            else if (isHomeAndTokenAFile()) {
                completion.addCompletionCandidate("");
                // append when we have a file
                completion.doAppendSeparator(true);
            }
            // not a directory or file, list what we find
            else {
                listPossibleDirectories(completion);
            }
        }
        else if (!startWithSlash() && !startWithWindowsDrive()) {
            if (isCwdAndTokenADirectory()) {
                if (tokenEndsWithSlash()) {
                    completion.addCompletionCandidates(
                        listDirectory(new File(cwd.getAbsolutePath() +
                            Config.getPathSeparator() + token), null));
                }
                else {
                    List<String> tmpDirs;
                    if (lastDir != null) {
                        tmpDirs = listDirectory(
                            new File(cwd.getAbsolutePath() + Config.getPathSeparator() + lastDir), rest);
                    }
                    else {
                        tmpDirs = listDirectory(cwd, rest);
                    }
                    if (tmpDirs.size() == 1 || endsWithParent())
                        completion.addCompletionCandidate(rest + Config.getPathSeparator());
                    else
                        completion.addCompletionCandidates(tmpDirs);
                }
            }
            else if (isCwdAndTokenAFile()) {
                listPossibleDirectories(completion);
                if (completion.getCompletionCandidates().size() == 1) {
                    completion.getCompletionCandidates().set(0, new TerminalString("", true));
                    // append when we have a file
                    completion.doAppendSeparator(true);
                }
                else if (completion.getCompletionCandidates().size() == 0) {
                    completion.addCompletionCandidate("");
                    // append when we have a file
                    completion.doAppendSeparator(true);
                }
            }
            // not a directory or file, list what we find
            else {
                listPossibleDirectories(completion);
            }
        }
        else if (startWithSlash() || startWithWindowsDrive()) {
            if (isTokenADirectory()) {
                if (tokenEndsWithSlash()) {
                    completion.addCompletionCandidates(
                        listDirectory(new File(token), null));
                }
                else
                    completion.addCompletionCandidate(Config.getPathSeparator());
            }
            else if (isTokenAFile()) {
                listPossibleDirectories(completion);
                if (completion.getCompletionCandidates().size() == 1) {
                    completion.getCompletionCandidates().set(0, new TerminalString("", true));
                    // completion.addCompletionCandidate("");
                    // append when we have a file
                    completion.doAppendSeparator(true);
                }
            }
            // not a directory or file, list what we find
            else {
                listPossibleDirectories(completion);
            }
        }

        // try to find if more than one filename start with the same word
        if (completion.getCompletionCandidates().size() > 1) {
            String startsWith = Parser.findStartsWithTerminalString(completion.getCompletionCandidates());
            if (startsWith.contains(" "))
                startsWith = Parser.switchEscapedSpacesToSpacesInWord(startsWith);
            if (startsWith != null && startsWith.length() > 0 && rest != null &&
                startsWith.length() > rest.length()) {
                completion.getCompletionCandidates().clear();
                completion.addCompletionCandidate(Parser.switchSpacesToEscapedSpacesInWord(startsWith));
            }
        }

        // new offset tweaking to match the "common" way of returning completions
        if (completion.getCompletionCandidates().size() == 1) {
            if (isTokenADirectory() && !tokenEndsWithSlash() && (startWithSlash() || startWithWindowsDrive())) {
                completion.getCompletionCandidates().get(0).setCharacters(token +
                    completion.getCompletionCandidates().get(0).getCharacters());

                completion.setOffset(completion.getCursor() - token.length());
            }
            else if (isTokenAFile()) {
                completion.getCompletionCandidates().get(0).setCharacters(token +
                    completion.getCompletionCandidates().get(0).getCharacters());

                completion.setOffset(completion.getCursor() - token.length());
                completion.doAppendSeparator(true);
            }
            else if (token != null) {
                if (rest != null && token.length() > rest.length()) {
                    completion.getCompletionCandidates().get(0).setCharacters(
                        Parser.switchSpacesToEscapedSpacesInWord(
                            token.substring(0, token.length() - rest.length())) +
                            completion.getCompletionCandidates().get(0).getCharacters());

                    completion.setOffset(completion.getCursor() - token.length());
                }
                else if (rest != null && token.length() == rest.length()) {
                    completion.setOffset(completion.getCursor() - (rest.length() + Parser.findNumberOfSpacesInWord(rest)));
                }
                else {
                    if (token.endsWith(Config.getPathSeparator()))
                        completion.getCompletionCandidates().get(0).setCharacters(
                            Parser.switchSpacesToEscapedSpacesInWord(token) +
                                completion.getCompletionCandidates().get(0).getCharacters());

                    completion.setOffset(completion.getCursor() - token.length());
                }
            }
            else {
                completion.setOffset(completion.getCursor());
            }
        }
        else if (completion.getCompletionCandidates().size() > 1) {
            completion.setIgnoreOffset(true);
            if (rest != null && rest.length() > 0)
                completion.setOffset(completion.getCursor() - rest.length());
        }
    }

    private void listPossibleDirectories(CompleteOperation completion) {
        List<String> returnFiles;

        if (startWithSlash()) {
            if (lastDir != null && lastDir.startsWith(Config.getPathSeparator()))
                returnFiles = listDirectory(new File(lastDir), rest);
            else
                returnFiles = listDirectory(new File(Config.getPathSeparator() + lastDir), rest);
        }
        else if (startWithWindowsDrive()) {
            if (lastDir != null && lastDir.length() == 2)
                returnFiles = listDirectory(new File(lastDir + Config.getPathSeparator()), rest);
            else
                returnFiles = listDirectory(new File(lastDir), rest);
        }
        else if (startWithHome()) {
            if (lastDir != null) {
                returnFiles = listDirectory(new File(Config.getHomeDir() + lastDir.substring(1)), rest);
            }
            else
                returnFiles = listDirectory(new File(Config.getHomeDir() + Config.getPathSeparator()), rest);
        }
        else if (lastDir != null) {
            returnFiles = listDirectory(new File(cwd +
                Config.getPathSeparator() + lastDir), rest);
        }
        else
            returnFiles = listDirectory(cwd, rest);

        completion.addCompletionCandidates(returnFiles);
    }

    private void findRestAndLastDir() {
        if (token.contains(Config.getPathSeparator())) {
            lastDir = token.substring(0, token.lastIndexOf(Config.getPathSeparator()));
            rest = token.substring(token.lastIndexOf(Config.getPathSeparator()) + 1);
        }
        else if (token.trim().isEmpty()) {
            lastDir = token;
        }
        else {
            rest = token;
        }
    }

    private boolean isTokenADirectory() {
        return new File(token).isDirectory();
    }

    private boolean isTokenAFile() {
        return new File(token).isFile();
    }

    private boolean isCwdAndTokenADirectory() {
        return new File(cwd.getAbsolutePath() +
            Config.getPathSeparator() + token).isDirectory();
    }

    private boolean isCwdAndTokenAFile() {
        return new File(cwd.getAbsolutePath() +
            Config.getPathSeparator() + token).isFile();
    }

    private boolean isHomeAndTokenADirectory() {
        return new File(Config.getHomeDir() +
            token.substring(1)).isDirectory();
    }

    private boolean isHomeAndTokenAFile() {
        return new File(Config.getHomeDir() +
            token.substring(1)).isFile();
    }

    private boolean endsWithParent() {
        return token.length() > 1 && token.lastIndexOf(PARENT) == token.length() - 2;
    }

    private boolean startWithHome() {
        return token.indexOf(HOME) == 0;
    }

    private boolean containStar() {
        int index = token.indexOf(STAR);
        if (index == 0 || (index > 0 && !(token.charAt(index - 1) == ESCAPE)))
            return true;
        else
            return false;
    }

    private boolean containWildCards() {
        int index = token.indexOf(WILDCARD);
        if (index == 0 || (index > 0 && !(token.charAt(index - 1) == ESCAPE)))
            return true;
        else
            return false;
    }

    private boolean startWithSlash() {
        return token.indexOf(Config.getPathSeparator()) == 0;
    }

    private boolean startWithWindowsDrive() {
        if (!Config.isOSPOSIXCompatible()) {
            for (File f : windowsRoots) {
                if (token.startsWith(f.toString())) {
                    return true;
                }
            }
            return false;
        }
        else
            return false;
    }

    private boolean tokenEndsWithSlash() {
        return token.lastIndexOf(Config.getPathSeparator()) == token.length() - 1;
    }

    private List<String> listDirectory(File path, String rest) {
        List<String> fileNames = new ArrayList<String>();
        if (path != null && path.isDirectory()) {
            for (File file : path.listFiles(fileFilter)) {
                if (rest == null || rest.length() == 0)
                    if (file.isDirectory())
                        fileNames.add(Parser.switchSpacesToEscapedSpacesInWord(file.getName()) + Config.getPathSeparator());
                    else
                        fileNames.add(Parser.switchSpacesToEscapedSpacesInWord(file.getName()));
                else {
                    if (file.getName().startsWith(rest)) {
                        if (file.isDirectory())
                            fileNames.add(Parser.switchSpacesToEscapedSpacesInWord(file.getName()) + Config.getPathSeparator());
                        else
                            fileNames.add(Parser.switchSpacesToEscapedSpacesInWord(file.getName()));
                    }
                }
            }
        }

        if (fileComparator == null)
            fileComparator = new PosixFileNameComparator();
        Collections.sort(fileNames, fileComparator);
        return fileNames;
    }

    @Override
    public String toString() {
        return "FileLister{" +
            "token='" + token + '\'' +
            ", cwd=" + cwd +
            ", rest='" + rest + '\'' +
            ", lastDir='" + lastDir + '\'' +
            '}';
    }
}
TOP

Related Classes of org.jboss.aesh.util.FileLister

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.