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 org.jboss.aesh.complete.CompleteOperation;
import org.jboss.aesh.console.Config;
import org.jboss.aesh.parser.Parser;
import org.jboss.aesh.terminal.TerminalString;

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

/**
* 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 char DOT = '.';
    private static final String home = "~/";
    private static final char TILDE = '~';
    private static final String parent = "..";
    private static final char STAR = '*';
    private static final char WILDCARD = '?';
    private static final char ESCAPE = '\\';

    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) {
        if(filter == Filter.ALL)
            fileFilter = new FileAndDirectoryFilter();
        else if(filter == Filter.FILE)
            fileFilter = new OnlyFileFilter();
        else if(filter == Filter.DIRECTORY)
            fileFilter = new DirectoryFileFilter();
        else
            fileFilter = new FileAndDirectoryNoDotNamesFilter();
    }

    /**
     * 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()) {
            if(isCwdAndTokenADirectory()) {
                if(tokenEndsWithSlash()) {
                    completion.addCompletionCandidates(
                            listDirectory(new File(cwd.getAbsolutePath() +
                                    Config.getPathSeparator()+token), null));
                }
                else {
                     List<String> tmpDirs = listDirectory(cwd, token);
                    if(tmpDirs.size() == 1 || endsWithParent())
                        completion.addCompletionCandidate( 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()) {
            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()) {
                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) {
            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(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(new File(cwd+Config.getPathSeparator()+token).exists())
                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.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 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 + '\'' +
                '}';
    }

    public static class DirectoryFileFilter implements FileFilter {
        @Override
        public boolean accept(File pathName) {
            return pathName.isDirectory();
        }
    }

    public static class FileAndDirectoryFilter implements FileFilter {
        @Override
        public boolean accept(File pathName) {
            return pathName.isDirectory() || pathName.isFile();
        }
    }

    //love this name :)
    public static class OnlyFileFilter implements FileFilter {
        @Override
        public boolean accept(File pathName) {
            return pathName.isFile();
        }
    }

    public static class FileAndDirectoryNoDotNamesFilter implements FileFilter {
        @Override
        public boolean accept(File pathname) {
            return !pathname.getName().startsWith(".");
        }
    }

    public enum Filter { FILE,DIRECTORY,ALL,NO_DOT_NAMES}

    public static class PosixFileNameComparator implements Comparator<String> {
        @Override
        public int compare(String o1, String o2) {
            if(o1.length() > 1 && o2.length() > 1) {
                if(o1.indexOf(DOT) == 0) {
                    if(o2.indexOf(DOT) == 0)
                        return o1.substring(1).compareToIgnoreCase(o2.substring(1));
                    else
                        return o1.substring(1).compareToIgnoreCase(o2);
                }
                else {
                    if(o2.indexOf(DOT) == 0)
                        return o1.compareToIgnoreCase(o2.substring(1));
                    else
                        return o1.compareToIgnoreCase(o2);
                }
            }
            else
                return 0;
        }
    }
}
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.