-
Notifications
You must be signed in to change notification settings - Fork 82
Unify VFS interfaces #2641
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Unify VFS interfaces #2641
Changes from all commits
51b6393
8adb46e
3cb33d9
f300250
052ae18
513ffb3
a144fe5
842881a
3284a32
16c4bb2
9fe54a6
82d2ae9
177f099
d494609
01d2b66
8febaae
f6328c8
9490e8c
8cebae8
b25f48c
387b853
f0de47f
0c56761
20f6541
a57d1c3
88a6696
2d1c2cc
674c6d8
8364a67
32b542a
1d728fd
cfc7cf6
4f975d3
fa96e91
f74831f
169d811
269b8f1
971fd4f
c7a57f7
1b2f38c
9d2862c
ebc14b2
b5f72f5
d28de94
a2e6234
65555f2
7a901fc
13fa13b
f6eb9ab
78de993
4c87e06
2f3e97d
df9b5ad
8e5db3f
e940415
eb7e4de
e44cb59
167847d
c7c087c
3fd308e
26a6c04
5135a40
2b67b36
dc27228
e9aeeac
0c44a28
68d76fe
3303ff5
6530f8a
1ea9070
e1d4dfc
abd9385
466cf1d
4491bc0
388ac3f
4654a6a
c2dd1f7
1a086e7
3ca1ae5
cd94881
9c29f77
3e452a8
dd5c50f
2bb863d
aecab65
ddae704
87240dd
15b59ab
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| /* | ||
| * Copyright (c) 2018-2026, NWO-I CWI and Swat.engineering | ||
| * All rights reserved. | ||
| * | ||
| * Redistribution and use in source and binary forms, with or without | ||
| * modification, are permitted provided that the following conditions are met: | ||
| * | ||
| * 1. Redistributions of source code must retain the above copyright notice, | ||
| * this list of conditions and the following disclaimer. | ||
| * | ||
| * 2. Redistributions in binary form must reproduce the above copyright notice, | ||
| * this list of conditions and the following disclaimer in the documentation | ||
| * and/or other materials provided with the distribution. | ||
| * | ||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
| * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
| * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
| * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE | ||
| * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
| * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
| * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
| * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
| * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
| * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
| * POSSIBILITY OF SUCH DAMAGE. | ||
| */ | ||
| package org.rascalmpl.uri; | ||
|
|
||
| public interface IExternalResolverRegistry extends ISourceLocationInputOutput, ILogicalSourceLocationResolver, ISourceLocationWatcher { | ||
| @Override | ||
| default String scheme() { | ||
| throw new UnsupportedOperationException("'scheme' is not supported for external resolvers"); | ||
| } | ||
|
|
||
| @Override | ||
| default String authority() { | ||
| throw new UnsupportedOperationException("`authority` is not supported for external resolvers"); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -44,7 +44,6 @@ public interface ISourceLocationWatcher { | |
| */ | ||
| boolean supportsRecursiveWatch(); | ||
|
|
||
|
|
||
| public interface ISourceLocationChanged { | ||
| ISourceLocation getLocation(); | ||
| ISourceLocationChangeType getChangeType(); | ||
|
|
@@ -63,9 +62,28 @@ default boolean isChanged() { | |
| } | ||
|
|
||
| public enum ISourceLocationChangeType { | ||
| CREATED(), | ||
| DELETED(), | ||
| MODIFIED() | ||
| CREATED(2), | ||
| DELETED(3), | ||
| MODIFIED(1); | ||
|
Comment on lines
+65
to
+67
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why this order of the numbers? (add a doc for it?) |
||
|
|
||
| private final int value; | ||
|
|
||
| public int getValue() { | ||
| return value; | ||
| } | ||
|
|
||
| ISourceLocationChangeType(int value) { | ||
| this.value = value; | ||
| } | ||
|
|
||
| public static ISourceLocationChangeType fromValue(int value) { | ||
| switch (value) { | ||
| case 2: return CREATED; | ||
| case 3: return DELETED; | ||
| case 1: return MODIFIED; | ||
| default: throw new IllegalArgumentException("Unknown ISourceLocationChangeType value " + value); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| static ISourceLocationChanged created(ISourceLocation loc) { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -44,6 +44,7 @@ | |
| import org.rascalmpl.unicode.UnicodeOutputStreamWriter; | ||
| import org.rascalmpl.uri.ISourceLocationWatcher.ISourceLocationChanged; | ||
| import org.rascalmpl.uri.classloaders.IClassloaderLocationResolver; | ||
| import org.rascalmpl.uri.remote.RemoteExternalResolverRegistry; | ||
| import org.rascalmpl.uri.watch.WatchRegistry; | ||
| import org.rascalmpl.values.IRascalValueFactory; | ||
| import org.rascalmpl.values.ValueFactoryFactory; | ||
|
|
@@ -65,12 +66,7 @@ public class URIResolverRegistry { | |
| private final Map<String, Map<String, ILogicalSourceLocationResolver>> logicalResolvers = new ConcurrentHashMap<>(); | ||
| private final Map<String, IClassloaderLocationResolver> classloaderResolvers = new ConcurrentHashMap<>(); | ||
|
|
||
| // we allow the user to define (using -Drascal.fallbackResolver=fully.qualified.classname) a single class that will handle | ||
| // scheme's not statically registered. That class should implement at least one of these interfaces | ||
| private volatile @Nullable ISourceLocationInput fallbackInputResolver; | ||
| private volatile @Nullable ISourceLocationOutput fallbackOutputResolver; | ||
| private volatile @Nullable ILogicalSourceLocationResolver fallbackLogicalResolver; | ||
| private volatile @Nullable IClassloaderLocationResolver fallbackClassloaderResolver; | ||
| private volatile @Nullable IExternalResolverRegistry externalRegistry; | ||
|
|
||
| private static class InstanceHolder { | ||
| static URIResolverRegistry sInstance = new URIResolverRegistry(); | ||
|
|
@@ -116,14 +112,38 @@ private void loadServices() { | |
| try { | ||
| Enumeration<URL> resources = getClass().getClassLoader().getResources(RESOLVERS_CONFIG); | ||
| Collections.list(resources).forEach(f -> loadServices(f)); | ||
| var fallbackResolverClassName = System.getProperty("rascal.fallbackResolver"); | ||
| if (fallbackResolverClassName != null) { | ||
| loadFallback(fallbackResolverClassName); | ||
| } | ||
| } | ||
| catch (IOException e) { | ||
| throw new Error("WARNING: Could not load URIResolverRegistry extensions from " + RESOLVERS_CONFIG, e); | ||
| } | ||
|
|
||
| var remoteResolverRegistryPort = getRemoteResolverRegistryPort(); | ||
| if (remoteResolverRegistryPort != null) { | ||
| synchronized (this) { | ||
| if (this.externalRegistry == null) { | ||
| registerRemoteResolverRegistry(new RemoteExternalResolverRegistry(remoteResolverRegistryPort)); | ||
| } | ||
| } | ||
| } | ||
| } | ||
|
|
||
| public static Integer getRemoteResolverRegistryPort() { | ||
| var remoteResolverRegistryPortProperty = System.getProperty("rascal.remoteResolverRegistryPort"); | ||
| if (remoteResolverRegistryPortProperty != null) { | ||
| try { | ||
| return Integer.parseInt(remoteResolverRegistryPortProperty); | ||
| } catch (NumberFormatException e) { | ||
| System.err.println("WARNING: Invalid remoteResolverRegistryPort environment variable: " + remoteResolverRegistryPortProperty + " is not parseable as integer"); | ||
| } | ||
| } | ||
| return null; | ||
| } | ||
|
|
||
| public synchronized void registerRemoteResolverRegistry(RemoteExternalResolverRegistry registry) { | ||
| synchronized (this) { | ||
|
Comment on lines
+142
to
+143
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What is the benefit of this I don't think this function should be public? I also think the |
||
| this.externalRegistry = registry; | ||
| watchers.setExternalRegistry(registry); | ||
| } | ||
| } | ||
|
|
||
rodinaarssen marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| public Set<String> getRegisteredInputSchemes() { | ||
|
|
@@ -153,46 +173,6 @@ private Object constructService(String name) throws ClassNotFoundException, Inst | |
| } | ||
| } | ||
|
|
||
| private void loadFallback(String fallbackClass) { | ||
| try { | ||
| Object instance = constructService(fallbackClass); | ||
| boolean ok = false; | ||
| if (instance instanceof ILogicalSourceLocationResolver) { | ||
| fallbackLogicalResolver = (ILogicalSourceLocationResolver) instance; | ||
| ok = true; | ||
| } | ||
|
|
||
| if (instance instanceof ISourceLocationInput) { | ||
| fallbackInputResolver = (ISourceLocationInput) instance; | ||
| ok = true; | ||
| } | ||
|
|
||
| if (instance instanceof ISourceLocationOutput) { | ||
| fallbackOutputResolver = (ISourceLocationOutput) instance; | ||
| ok = true; | ||
| } | ||
|
|
||
| if (instance instanceof IClassloaderLocationResolver) { | ||
| fallbackClassloaderResolver = (IClassloaderLocationResolver) instance; | ||
| ok = true; | ||
| } | ||
|
|
||
| if (instance instanceof ISourceLocationWatcher) { | ||
| watchers.setFallback((ISourceLocationWatcher) instance); | ||
| } | ||
| if (!ok) { | ||
| System.err.println("WARNING: could not load fallback resolver " + fallbackClass | ||
| + " because it does not implement ISourceLocationInput or ISourceLocationOutput or ILogicalSourceLocationResolver"); | ||
| } | ||
| } | ||
| catch (ClassNotFoundException | InstantiationException | IllegalAccessException | ClassCastException | ||
| | IllegalArgumentException | InvocationTargetException | SecurityException e) { | ||
| System.err.println("WARNING: could not load resolver due to " + e.getMessage()); | ||
| e.printStackTrace(); | ||
| } | ||
|
|
||
| } | ||
|
|
||
| private void loadServices(URL nextElement) { | ||
| try { | ||
| for (String name : readConfigFile(nextElement)) { | ||
|
|
@@ -402,9 +382,9 @@ private ISourceLocation physicalLocation(ISourceLocation loc) throws IOException | |
| loc = resolveAndFixOffsets(loc, resolver, map.values()); | ||
| } | ||
|
|
||
| if (fallbackLogicalResolver != null) { | ||
| var fallbackResult = resolveAndFixOffsets(loc == null ? original : loc, fallbackLogicalResolver, Collections.emptyList()); | ||
| return fallbackResult == null ? loc : fallbackResult; | ||
| if (externalRegistry != null) { | ||
| var externalResult = resolveAndFixOffsets(loc == null ? original : loc, externalRegistry, Collections.emptyList()); | ||
| return externalResult == null ? loc : externalResult; | ||
| } | ||
| return loc; | ||
| } | ||
|
|
@@ -464,7 +444,7 @@ private ISourceLocationInput getInputResolver(String scheme) { | |
| return result; | ||
| } | ||
| } | ||
| return fallbackInputResolver; | ||
| return externalRegistry; | ||
| } | ||
| return result; | ||
| } | ||
|
|
@@ -480,7 +460,6 @@ private IClassloaderLocationResolver getClassloaderResolver(String scheme) { | |
| return result; | ||
| } | ||
| } | ||
| return fallbackClassloaderResolver; | ||
toinehartman marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| } | ||
| return result; | ||
| } | ||
|
|
@@ -496,7 +475,7 @@ private ISourceLocationOutput getOutputResolver(String scheme) { | |
| return result; | ||
| } | ||
| } | ||
| return fallbackOutputResolver; | ||
| return externalRegistry; | ||
| } | ||
| return result; | ||
| } | ||
|
|
@@ -1118,7 +1097,7 @@ public boolean hasLogicalResolver(ISourceLocation loc) { | |
| } | ||
|
|
||
| public boolean hasNativelyWatchableResolver(ISourceLocation loc) { | ||
| return watchers.hasNativeSupport(loc.getScheme()) || watchers.hasNativeSupport(safeResolve(loc).getScheme()) || watchers.hasFallback(); | ||
| return watchers.hasNativeSupport(loc.getScheme()) || watchers.hasNativeSupport(safeResolve(loc).getScheme()) || watchers.hasExternalRegistry(); | ||
| } | ||
|
|
||
| public FileAttributes stat(ISourceLocation loc) throws IOException { | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.