Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions src/org/rascalmpl/uri/ILogicalSourceLocationResolver.java
Original file line number Diff line number Diff line change
@@ -1,11 +1,36 @@
/*******************************************************************************
* Copyright (c) 2009-2025 CWI
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* * Jurgen J. Vinju - [email protected] - CWI
*******************************************************************************/

package org.rascalmpl.uri;

import java.io.IOException;

import io.usethesource.vallang.ISourceLocation;

/**
* A logical resolver translates locations keyed by their scheme and (optionally) their authority
* to a lower level scheme. Logical resolvers may translate to other logical resolvers, but
* most of them map directly to a physical location like file:///
*/
public interface ILogicalSourceLocationResolver {
ISourceLocation resolve(ISourceLocation input) throws IOException;
String scheme();
String authority();

/**
* Some logical resolver may collect entries from more than one location,
* hence first resolving and then calling ISourceLocationInput.list(..) won't do.
* An example is the PATH:/// resolver.
*/
default String[] resolveList(ISourceLocation input) throws IOException {
return URIResolverRegistry.getInstance().listEntries(resolve(input));
}
}
20 changes: 13 additions & 7 deletions src/org/rascalmpl/uri/URIResolverRegistry.java
Original file line number Diff line number Diff line change
Expand Up @@ -709,16 +709,22 @@ private boolean isRootLogical(ISourceLocation uri) {
}

public String[] listEntries(ISourceLocation uri) throws IOException {
uri = safeResolve(uri);
if (isRootLogical(uri)) {
// if it's a location without any path and authority
// we want to list possible authorities if it's a logical one
// (logical resolvers cannot handle this call themselves)
Map<String, ILogicalSourceLocationResolver> candidates = logicalResolvers.get(uri.getScheme());
if (candidates != null) {
Map<String, ILogicalSourceLocationResolver> candidates = logicalResolvers.get(uri.getScheme());

if (candidates != null && !candidates.isEmpty()) {
// this is a logical uri. we defer to resolveList to allow for the logical resolver to concatenate from
// different sources. But not if the authority and the path are empty, then we list the available authorities
if (isRootLogical(uri) && candidates.size() > 1) {
return candidates.keySet().toArray(new String[0]);
}

String auth = uri.hasAuthority() ? uri.getAuthority() : "";
ILogicalSourceLocationResolver resolver = candidates.get(auth);

return resolver.resolveList(uri);
}

uri = safeResolve(uri);
ISourceLocationInput resolver = getInputResolver(uri.getScheme());

if (resolver == null) {
Expand Down
37 changes: 33 additions & 4 deletions src/org/rascalmpl/uri/file/SystemPathURIResolver.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
package org.rascalmpl.uri.file;

import java.io.File;
import java.io.IOException;
import java.util.stream.Stream;
import java.util.Arrays;

import org.rascalmpl.uri.ILogicalSourceLocationResolver;
Expand All @@ -32,23 +34,50 @@ public String scheme() {
return "PATH";
}


@Override
public ISourceLocation resolve(ISourceLocation input) {
private Stream<ISourceLocation> pathStream() {
String thePath = System.getenv("PATH");
if (thePath == null) {
return input;
return Stream.<ISourceLocation>empty();
}

return Arrays.stream(thePath.split(File.pathSeparator))
.map(FileURIResolver::constructFileURI)
.filter(URIResolverRegistry.getInstance()::exists);
}

@Override
public ISourceLocation resolve(ISourceLocation input) {
return pathStream()
.map(r -> URIUtil.getChildLocation(r, input.getPath()))
.filter(URIResolverRegistry.getInstance()::exists)
.findFirst()
.orElse(input)
;
}

@Override
public String[] resolveList(ISourceLocation input) {
return pathStream()
.map(r -> URIUtil.getChildLocation(r, input.getPath()))
.filter(URIResolverRegistry.getInstance()::exists)
.flatMap(r -> {
// here we concatenate the `.list()` for all folders in the path
try {
if (URIResolverRegistry.getInstance().isDirectory(r)) {
return Arrays.stream(URIResolverRegistry.getInstance().listEntries(r));
}
else {
return Stream.empty();
}
}
catch (IOException e) {
return null;
}
})
.filter(o -> o != null)
.toArray(String[]::new);
}

@Override
public String authority() {
return "";
Expand Down
Loading