Package org.jboss.aesh.util

Source Code of org.jboss.aesh.util.PathResolver$DirectoryFilter

/*
* Copyright 2012 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.console.Config;

import java.io.File;
import java.io.IOException;
import java.nio.file.DirectoryStream;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.PathMatcher;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;

/**
* Resolve a file that might contain (~,*,?) to its proper parentPath
* Returns a list of files.
* @author <a href="mailto:stale.pedersen@jboss.org">Ståle W. Pedersen</a>
*/
public class PathResolver {

    private static final char SEPARATOR = Config.getPathSeparator().charAt(0);
    private static final char TILDE = '~';
    private static final String TILDE_WITH_SEPARATOR = "~"+Config.getPathSeparator();
    private static final char STAR = '*';
    private static final char WILDCARD = '?';
    private static final String PARENT = "..";
    private static final String PARENT_WITH_SEPARATOR = ".."+ Config.getPathSeparator();
    private static final String ROOT = Config.getPathSeparator();
    private static final String CURRENT_WITH_SEPARATOR = "."+Config.getPathSeparator();
    private static final String SEPARATOR_WITH_CURRENT = Config.getPathSeparator()+".";
    private static final String SEPARATOR_CURRENT_SEPARATOR = Config.getPathSeparator()+"."+Config.getPathSeparator();
    private static final String CURRENT = ".";
    private static Pattern starPattern = Pattern.compile("[\\*]+");

    /**
     * 1. find the absolute root directory
     * 2. check for wildcards
     *
     * @param incPath
     * @param cwd
     * @return
     */
    @SuppressWarnings("IndexOfReplaceableByContains")
    public static List<File> resolvePath(File incPath, File cwd) {
        if(cwd == null)
            cwd = new File(Config.getHomeDir());

        //if incPath start with eg: ./, remove it
        if(incPath.toString().startsWith(CURRENT_WITH_SEPARATOR)) {
            incPath = new File(incPath.toString().substring(CURRENT_WITH_SEPARATOR.length()));
        }

        //if incPath == ., clear it
        if(incPath.toString().equals(CURRENT))
            incPath = new File("");

        if(incPath.toString().startsWith(TILDE_WITH_SEPARATOR)) {
            if(Config.getHomeDir().endsWith(Config.getPathSeparator()))
                incPath = new File(Config.getHomeDir()+incPath.toString().substring(2));
            else
                incPath = new File(Config.getHomeDir()+incPath.toString().substring(1));
        }

        if(incPath.toString().indexOf(TILDE) == 0) {
            if(incPath.toString().length() > 1)
                incPath = new File(Config.getPathSeparator() + incPath.toString().substring(1));
            else
                incPath = new File(Config.getPathSeparator());
        }

        //  foo1/./foo2 is changed to foo1/foo2
        if(incPath.toString().indexOf(SEPARATOR_CURRENT_SEPARATOR) > -1) {
            int index = incPath.toString().indexOf(SEPARATOR_CURRENT_SEPARATOR);
            if(index == 0) {
                incPath = new File(incPath.toString().substring(SEPARATOR_CURRENT_SEPARATOR.length()-1));
            }
            else {
                incPath = new File(incPath.toString().substring(0, index) +
                        incPath.toString().substring(index+2, incPath.toString().length()));
            }
        }

        // foo1/foo2/. is changed to foo1/foo2
        if(incPath.toString().endsWith(SEPARATOR_WITH_CURRENT)) {
            incPath = new File(incPath.toString().substring(0, incPath.toString().length()-SEPARATOR_WITH_CURRENT.length()));
        }

        //parentPath do not start with / and cwd is not / either
        if(incPath.toString().indexOf(ROOT) != 0 && !cwd.toString().equals(ROOT)) {
            if(cwd.toString().endsWith(Config.getPathSeparator()))
                incPath = new File(cwd.toString() + incPath.toString());
            else
                incPath = new File(cwd.toString() + Config.getPathSeparator() + incPath.toString());
        }

        if(incPath.toString().indexOf(PARENT_WITH_SEPARATOR) > -1) {
            String tmp = incPath.toString();
            File tmpFile = new File(incPath.toString());
            while(tmp.indexOf(PARENT_WITH_SEPARATOR) > -1) {
                int index = tmp.indexOf(PARENT_WITH_SEPARATOR);
                if(index == 0) {
                    tmp = tmp.substring(PARENT_WITH_SEPARATOR.length());
                    tmpFile = new File(Config.getPathSeparator());
                }
                else {
                    tmpFile = new File(tmp.substring(0, index));
                    tmpFile = tmpFile.getParentFile();
                    if(tmpFile == null)
                        tmpFile = new File(Config.getPathSeparator());
                    tmpFile = new File(tmpFile.toString() + tmp.substring(index+ PARENT_WITH_SEPARATOR.length()-1));
                    //tmp = tmp.substring(0, index) + tmp.substring(index+PARENT_WITH_SEPARATOR.length());
                    tmp = tmpFile.toString();
                }
            }
            incPath = new File(tmp);
        }

        if(incPath.toString().endsWith(PARENT)) {
            incPath = new File(incPath.toString().substring(0, incPath.toString().length()-PARENT.length()));
            incPath = incPath.getParentFile();
            if(incPath == null)
                incPath = new File(Config.getPathSeparator());
        }

        if( incPath.toString().indexOf(STAR) > -1 || incPath.toString().indexOf(WILDCARD) > -1) {
            PathCriteria pathCriteria = parsePath(incPath);
            List<File> foundFiles = findFiles(new File(pathCriteria.parentPath), pathCriteria.getCriteria(), false);
            if(pathCriteria.childPath.length() == 0)
                return foundFiles;
            else {
                List<File> outFiles = new ArrayList<>();
                for(File f : foundFiles)
                    if(new File(f+Config.getPathSeparator()+pathCriteria.childPath).exists())
                        outFiles.add(new File(f+Config.getPathSeparator()+pathCriteria.childPath));

                return outFiles;
            }
        }
        else {
            //no wildcards
            ArrayList<File> fileList = new ArrayList<File>(1);
            fileList.add(incPath);
            return fileList;
        }
    }

    private static List<File> parseWildcard(File incPath) {
        ArrayList<File> files = new ArrayList<File>();
        int index = -1;
        while(incPath.toString().indexOf(STAR) > -1) {

        }

        return files;
    }

    private static List<File> findFiles(File incPath, String searchArgument, boolean findDirectory) {
        ArrayList<File> files = new ArrayList<>();

        final PathMatcher matcher = FileSystems.getDefault().getPathMatcher("glob:**");
         DirectoryStream.Filter<Path> filter = new DirectoryStream.Filter<Path>() {
            @Override
            public boolean accept(Path entry)  {
                return matcher.matches(entry.getFileName());
            }
        };

        if(starPattern.matcher(searchArgument).matches()) {
            try (DirectoryStream<Path> stream = Files.newDirectoryStream(incPath.toPath(), new DirectoryFilter())) {
                for(Path p : stream)
                    files.add(p.toFile());
                return files;
            }
            catch (IOException e) {
                e.printStackTrace();
            }
        }
        else {
            try (DirectoryStream<Path> stream = Files.newDirectoryStream(incPath.toPath(), searchArgument)) {
                if(findDirectory) {
                    for(Path p : stream)
                        if(Files.isDirectory(p))
                            files.add(p.toFile());
                }
                else {
                    for(Path p : stream)
                        files.add(p.toFile());
                }
                return files;
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        return files;
    }

    private static class DirectoryFilter implements DirectoryStream.Filter<Path> {
        @Override
        public boolean accept(Path entry) throws IOException {
            return Files.isDirectory(entry);
        }
    }

    private static PathCriteria parsePath(File path) {
        int starIndex = path.toString().indexOf(STAR);
        int wildcardIndex = path.toString().indexOf(WILDCARD);

        int index = (starIndex < wildcardIndex || wildcardIndex < 0) ? starIndex : wildcardIndex;

        if(index == 0 && path.toString().length() == 1)
            return new PathCriteria(String.valueOf(SEPARATOR), "", path.toString());
        else {
            int parentSeparatorIndex = index-1;
            while(path.toString().charAt(parentSeparatorIndex) != SEPARATOR && parentSeparatorIndex > -1)
                parentSeparatorIndex--;

            int childSeparatorIndex = index+1;
            if(childSeparatorIndex < path.toString().length())
                while(path.toString().charAt(childSeparatorIndex) != SEPARATOR && parentSeparatorIndex < path.toString().length())
                    childSeparatorIndex++;

            String parentPath = path.toString().substring(0, parentSeparatorIndex);
            String criteria = path.toString().substring(parentSeparatorIndex+1, childSeparatorIndex);
            String childPath = path.toString().substring(childSeparatorIndex, path.toString().length());

            return new PathCriteria(parentPath, childPath, criteria);
        }
    }

    static class PathCriteria {
        private String parentPath;
        private String childPath;
        private String criteria;

        PathCriteria(String parentPath, String childPath, String criteria) {
            this.parentPath = parentPath;
            this.childPath = childPath;
            this.criteria = criteria;
        }

        public String getParentPath() {
            return parentPath;
        }

        public String getCriteria() {
            return criteria;
        }

        public String getChildPath() {
            return childPath;
        }
    }
}
TOP

Related Classes of org.jboss.aesh.util.PathResolver$DirectoryFilter

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.