
org.aesh.io.PathResolver Maven / Gradle / Ivy
The newest version!
/*
* JBoss, Home of Professional Open Source
* Copyright 2014 Red Hat Inc. and/or its affiliates and other contributors
* as indicated by the @authors tag. All rights reserved.
* See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.aesh.io;
import org.aesh.terminal.utils.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 Ståle W. Pedersen
*/
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 DRIVER_SEPARATOR = ":";
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 final Pattern starPattern = Pattern.compile("[\\*]+");
/**
* 1. find the absolute root directory
* 2. check for wildcards
*
* @param incPath
* @param cwd
* @return
*/
@SuppressWarnings("IndexOfReplaceableByContains")
public static List 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.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) {
// directories which name starts with tilde
incPath = new File(cwd.toString() + Config.getPathSeparator() + incPath.toString());
} else {
incPath = new File(Config.getHomeDir());
}
}
// 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()));
}
}
//parentPath do not start with / or by a windows driver letter and cwd is not / either
if( incPath.toString().indexOf(ROOT) != 0 && incPath.toString().indexOf(DRIVER_SEPARATOR) == -1 && !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();
while(tmp.indexOf(PARENT_WITH_SEPARATOR) > -1) {
int index = tmp.indexOf(PARENT_WITH_SEPARATOR);
if(index == 0) {
tmp = tmp.substring(PARENT_WITH_SEPARATOR.length());
}
else {
File 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);
if(incPath.toString().indexOf(SEPARATOR) > -1) {
List foundFiles = null;
if(pathCriteria.getCriteria().equals(String.valueOf(STAR))) {
foundFiles = new ArrayList<>();
foundFiles.add(new File(pathCriteria.getParentPath()));
}
else
foundFiles = findFiles(new File(pathCriteria.parentPath), pathCriteria.getCriteria(), false);
if(pathCriteria.childPath.length() == 0)
return foundFiles;
else {
List 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;
}
}
//just wildcard without separators
else {
if(incPath.toString().length() == 1) {
List foundFiles = findFiles(new File(pathCriteria.parentPath), pathCriteria.getCriteria(), false);
if(pathCriteria.childPath.length() == 0)
return foundFiles;
}
return new ArrayList();
}
}
else {
//no wildcards
ArrayList fileList = new ArrayList<>(1);
fileList.add(incPath);
return fileList;
}
}
private static List parseWildcard(File incPath) {
ArrayList files = new ArrayList<>();
int index = -1;
while(incPath.toString().indexOf(STAR) > -1) {
}
return files;
}
private static List findFiles(File incPath, String searchArgument, boolean findDirectory) {
ArrayList files = new ArrayList<>();
final PathMatcher matcher = FileSystems.getDefault().getPathMatcher("glob:**");
/*
DirectoryStream.Filter filter = new DirectoryStream.Filter() {
@Override
public boolean accept(Path entry) {
return matcher.matches(entry.getFileName());
}
};
*/
if(starPattern.matcher(searchArgument).matches()) {
try (DirectoryStream stream = findDirectory ?
Files.newDirectoryStream(incPath.toPath(), new DirectoryFilter()) :
Files.newDirectoryStream(incPath.toPath(), new FileFilter())) {
for(Path p : stream)
files.add(p.toFile());
return files;
}
catch (IOException e) {
e.printStackTrace();
}
}
else {
try (DirectoryStream 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 {
@Override
public boolean accept(Path entry) throws IOException {
return Files.isDirectory(entry);
}
}
private static class FileFilter implements DirectoryStream.Filter {
@Override
public boolean accept(Path entry) throws IOException {
return Files.exists(entry);
}
}
//todo: path criteria need to check if separator is in the path
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 final String parentPath;
private final String childPath;
private final 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;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy