Skip to content

Commit

Permalink
Tests fails when basedir has space
Browse files Browse the repository at this point in the history
Fixes eclipse#749

Signed-off-by: azerr <azerr@redhat.com>
  • Loading branch information
angelozerr committed Jun 26, 2020
1 parent e564c60 commit 399e5d3
Show file tree
Hide file tree
Showing 8 changed files with 128 additions and 67 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -82,12 +82,16 @@ public FilesChangedTracker() {
*/
public void addFileURI(String fileURI) {
try {
files.add(new FileChangedTracker(Paths.get(new URI(fileURI))));
addFileURI(new URI(fileURI));
} catch (URISyntaxException e) {
LOGGER.log(Level.SEVERE, "Add file URI to track failed", e);
}
}

public void addFileURI(URI fileURI) {
files.add(new FileChangedTracker(Paths.get(fileURI)));
}

/**
* Returns true if one file has changed and false otherwise.
*
Expand All @@ -101,4 +105,5 @@ public boolean isDirty() {
}
return false;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,17 @@

import static org.eclipse.lemminx.utils.FilesUtils.convertToWindowsPath;
import static org.eclipse.lemminx.utils.FilesUtils.getFilePathSlash;
import static org.eclipse.lemminx.utils.FilesUtils.getNormalizedPath;
import static org.eclipse.lemminx.utils.OSUtils.isWindows;
import static org.eclipse.lemminx.utils.StringUtils.isEmpty;

import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.net.URI;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

import org.eclipse.lemminx.commons.BadLocationException;
import org.eclipse.lemminx.dom.DOMDocument;
Expand All @@ -45,48 +48,50 @@ public class FilePathCompletionParticipant extends CompletionParticipantAdapter
public static final String FILE_SCHEME = "file";

@Override
public void onAttributeValue(String valuePrefix,
ICompletionRequest request, ICompletionResponse response) throws Exception {
public void onAttributeValue(String valuePrefix, ICompletionRequest request, ICompletionResponse response)
throws Exception {

DOMDocument xmlDocument = request.getXMLDocument();
String text = xmlDocument.getText();
Range fullRange = request.getReplaceRange();

// Get full attribute value range
int documentStartOffset = xmlDocument.offsetAt(fullRange.getStart());

String fullAttributeValue = valuePrefix;
if (isEmpty(fullAttributeValue)) {
return;
}

// Get value and range from fullAttributeValue
int completionOffset = request.getOffset(); // offset after the typed character
int parsedAttributeStartOffset = StringUtils.getOffsetAfterWhitespace(fullAttributeValue, completionOffset - documentStartOffset) + documentStartOffset; // first character of URI
int parsedAttributeStartOffset = StringUtils.getOffsetAfterWhitespace(fullAttributeValue,
completionOffset - documentStartOffset) + documentStartOffset; // first character of URI
String attributePath = text.substring(parsedAttributeStartOffset, completionOffset);

Position startValue = xmlDocument.positionAt(parsedAttributeStartOffset);
Position endValue = xmlDocument.positionAt(completionOffset);
fullRange = new Range(startValue, endValue);

// Try to get the URI string from the attribute value in case it has a file scheme
// Try to get the URI string from the attribute value in case it has a file
// scheme
// header (eg: "file://")
String osSpecificAttributePath = attributePath;
boolean hasFileScheme = false;

hasFileScheme = attributePath.startsWith(FilesUtils.FILE_SCHEME);
if (hasFileScheme) {
osSpecificAttributePath = attributePath.substring(FilesUtils.FILE_SCHEME.length());
osSpecificAttributePath = attributePath;// .substring(FilesUtils.FILE_SCHEME.length());
}

String slashInAttribute = getFilePathSlash(attributePath);

if (hasFileScheme) {
if (!osSpecificAttributePath.startsWith("/")) {
return; // use of 'file://' and the path was not absolute
// return; // use of 'file://' and the path was not absolute
}
if (isWindows && osSpecificAttributePath.length() == 1) { // only '/', so list Windows Drives

Range replaceRange = adjustReplaceRange(xmlDocument, fullRange, attributePath, "/");

File[] drives = File.listRoots();
Expand All @@ -96,86 +101,105 @@ public void onAttributeValue(String valuePrefix,
return;
}
}

if(isWindows) {
osSpecificAttributePath = convertToWindowsPath(osSpecificAttributePath);
}
else if("\\".equals(slashInAttribute)) { // Backslash used in Unix

if (isWindows) {
// osSpecificAttributePath = convertToWindowsPath(osSpecificAttributePath);
} else if ("\\".equals(slashInAttribute)) { // Backslash used in Unix
osSpecificAttributePath = osSpecificAttributePath.replace("\\", "/");
}

// Get the normalized URI string from the parent directory file if necessary
String workingDirectory = null; // The OS specific path for a working directory

if (!hasFileScheme) { //The path from the attribute value is not a uri, so we might need to reference the working directory path
if (!hasFileScheme) { // The path from the attribute value is not a uri, so we might need to reference
// the working directory path
String uriString = xmlDocument.getTextDocument().getUri();
URI uri = new URI(uriString);
URI uri = new URI(uriString.replace(" ", "%20"));

if(!FILE_SCHEME.equals(uri.getScheme())) {
if (!FILE_SCHEME.equals(uri.getScheme())) {
return;
}

String uriPathString = uri.getPath();
if(!uriPathString.startsWith("/")) {
return; //file uri is incorrect
if (!uriPathString.startsWith("/")) {
return; // file uri is incorrect
}
int lastSlash = uriPathString.lastIndexOf("/");
if(lastSlash > -1) {
if (lastSlash > -1) {
workingDirectory = uriPathString.substring(0, lastSlash);

if(isWindows) {
if (isWindows) {
// Necessary, so that this path is readable in Windows
workingDirectory = convertToWindowsPath(workingDirectory);
}
}
}

String uriString = xmlDocument.getTextDocument().getUri();
uriString = uriString.replace("file:///", "").replace("file://", "");
// URI uri = URIUtils.getURI(uriString);
Path workingDirectoryPath = Paths.get(uriString).getParent();

boolean result = Files.exists(workingDirectoryPath);
System.err.println(result);

boolean hasSh = attributePath.indexOf(":") == -1;

//Try to get a correctly formatted path from the given values
Path validAttributeValuePath = getNormalizedPath(workingDirectory, osSpecificAttributePath);
String p = attributePath.replaceAll("%20", " ").replace("file:///", "").replace("file://", "");

if(validAttributeValuePath == null) {
Path validAttributeValuePath = hasSh || p.startsWith("\\")
|| p.startsWith("\\") ? workingDirectoryPath.resolve(Paths.get(p)).normalize()
: Paths.get(p);
result = Files.exists(validAttributeValuePath);
System.err.println(result);
// Try to get a correctly formatted path from the given values
// Path validAttributeValuePath = getNormalizedPath(workingDirectory,
// osSpecificAttributePath);

if (validAttributeValuePath == null) {
return;
}

//Get adjusted range for the completion item (insert at end, or overwrite some existing text in the path)
// Get adjusted range for the completion item (insert at end, or overwrite some
// existing text in the path)
Range replaceRange = adjustReplaceRange(xmlDocument, fullRange, attributePath, slashInAttribute);

createNextValidCompletionPaths(validAttributeValuePath, slashInAttribute, replaceRange, response, null);
}

/**
* Returns a Range that covers trailing content after a slash, or
* if it already ends with a slash then a Range right after it.
* Returns a Range that covers trailing content after a slash, or if it already
* ends with a slash then a Range right after it.
*
* @param xmlDocument
* @param fullRange
* @param attributeValue
* @param slash
* @return
*/
private Range adjustReplaceRange(DOMDocument xmlDocument, Range fullRange, String attributeValue, String slash) {
//In the case the currently typed file/directory needs to be overwritten
// In the case the currently typed file/directory needs to be overwritten
Position replaceStart = null;
Position currentEnd = fullRange.getEnd();

int startOffset;
try {
startOffset = xmlDocument.offsetAt(fullRange.getStart());
} catch (BadLocationException e) {
return null;
}
int lastSlashIndex = attributeValue.lastIndexOf(slash);
if(lastSlashIndex > -1) {
if (lastSlashIndex > -1) {
try {
replaceStart = xmlDocument.positionAt(startOffset + lastSlashIndex);
} catch (BadLocationException e) {
return null;
}
}
Range replaceRange = new Range();
if(replaceStart != null) {
if (replaceStart != null) {
replaceRange.setStart(replaceStart);
}
else {
} else {
replaceRange.setStart(currentEnd);
}
replaceRange.setEnd(currentEnd);
Expand All @@ -185,27 +209,38 @@ private Range adjustReplaceRange(DOMDocument xmlDocument, Range fullRange, Strin

/**
* Creates the completion items based off the given absolute path
*
* @param pathToAttributeDirectory
* @param attributePath
* @param replaceRange
* @param response
* @param filter
*/
private void createNextValidCompletionPaths(Path pathToAttributeDirectory, String slash, Range replaceRange, ICompletionResponse response,
FilenameFilter filter) {

File[] proposedFiles = gatherFiles(pathToAttributeDirectory, filter);
if (proposedFiles != null) {
for (File child : proposedFiles) {
if (child != null) {
createFilePathCompletionItem(child, replaceRange, response, slash);
}
private void createNextValidCompletionPaths(Path pathToAttributeDirectory, String slash, Range replaceRange,
ICompletionResponse response, FilenameFilter filter) {

try (DirectoryStream<Path> stream = Files.newDirectoryStream(pathToAttributeDirectory)) {
for (Path entry : stream) {
createFilePathCompletionItem(entry.toFile(), replaceRange, response, slash);
// System.out.println(entry.getFileName());
}
} catch (IOException x) {
System.err.println(x);
}
//
// File[] proposedFiles = gatherFiles(pathToAttributeDirectory, filter);
// if (proposedFiles != null) {
// for (File child : proposedFiles) {
// if (child != null) {
// createFilePathCompletionItem(child, replaceRange, response, slash);
// }
// }
// }
}

/**
* Returns a list of File objects that are in the given directory
*
* @param pathOfDirectory
* @param filter
* @return
Expand All @@ -218,17 +253,17 @@ private File[] gatherFiles(Path pathOfDirectory, FilenameFilter filter) {
private void createFilePathCompletionItem(File f, Range replaceRange, ICompletionResponse response, String slash) {
CompletionItem item = new CompletionItem();
String fName = f.getName();
if(isWindows && fName.isEmpty()) { // Edge case for Windows drive letter
if (isWindows && fName.isEmpty()) { // Edge case for Windows drive letter
fName = f.getPath();
fName = fName.substring(0, fName.length() - 1);
}
String insertText;
insertText = slash + fName;
item.setLabel(insertText);

CompletionItemKind kind = f.isDirectory()? CompletionItemKind.Folder : CompletionItemKind.File;
CompletionItemKind kind = f.isDirectory() ? CompletionItemKind.Folder : CompletionItemKind.File;
item.setKind(kind);

item.setSortText(CompletionSortTextHelper.getSortText(kind));
item.setFilterText(insertText);
item.setTextEdit(new TextEdit(replaceRange, insertText));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.Writer;
import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
Expand Down Expand Up @@ -241,7 +242,8 @@ public static Path getNormalizedPath(String parentDirectory, String givenPath) {

private static Path getPathIfExists(String path) {
try {
Path p = Paths.get(path).normalize();
Path p = Paths.get(new URI(path));
p = p.normalize();
return p.toFile().exists() ? p : null;
} catch (Exception e) {
return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
*******************************************************************************/
package org.eclipse.lemminx.utils;

import java.net.URI;
import java.net.URISyntaxException;

/**
* URIUtils
*/
Expand Down Expand Up @@ -61,4 +64,12 @@ public static String sanitizingUri(String uri) {
}
return uri;
}

public static URI getURI(String uriString) throws URISyntaxException {
if (uriString == null) {
return null;
}
uriString = uriString.replaceAll(" ", "%20");
return new URI(uriString);
}
}
Loading

0 comments on commit 399e5d3

Please sign in to comment.