-
Notifications
You must be signed in to change notification settings - Fork 243
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
Re-Ordering priority in SeekableStreamFactory #1693
Merged
Merged
Changes from all commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
6cdcbd4
Re-Ordering priority in SeekableStreamFactory
lbergelson b949659
Also handling ParsingUtils
lbergelson 9eca91a
update HtsPath to throw on non file schemes with malformed URIs inste…
lbergelson 5376f55
try this
lbergelson 652eda2
respond to comments
lbergelson File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -23,12 +23,15 @@ | |
*/ | ||
package htsjdk.samtools.seekablestream; | ||
|
||
import htsjdk.samtools.util.IOUtil; | ||
import java.io.File; | ||
import htsjdk.io.HtsPath; | ||
import htsjdk.io.IOPath; | ||
import htsjdk.tribble.TribbleException; | ||
|
||
import java.io.IOException; | ||
import java.net.URI; | ||
import java.net.URL; | ||
import java.nio.channels.SeekableByteChannel; | ||
import java.nio.file.Path; | ||
import java.util.Set; | ||
import java.util.function.Function; | ||
|
||
/** | ||
|
@@ -40,6 +43,14 @@ | |
public class SeekableStreamFactory{ | ||
|
||
private static final ISeekableStreamFactory DEFAULT_FACTORY; | ||
private static final String HTTP = "http"; | ||
private static final String HTTPS = "https"; | ||
private static final String FTP = "ftp"; | ||
/** | ||
* the set of url schemes that have special support in htsjdk that isn't through a FileSystemProvider | ||
*/ | ||
private static final Set<String> URL_SCHEMES_WITH_LEGACY_SUPPORT = Set.of(HTTP, FTP, HTTPS); | ||
public static final String FILE_SCHEME = "file"; | ||
private static ISeekableStreamFactory currentFactory; | ||
|
||
static{ | ||
|
@@ -61,9 +72,28 @@ public static ISeekableStreamFactory getInstance(){ | |
* Does this path point to a regular file on disk and not something like a URL? | ||
* @param path the path to test | ||
* @return true if the path is to a file on disk | ||
* @deprecated this method is simplistic and no longer particularly useful since IOPath allows similar access to | ||
* various non-file data sources, internal use has been replaced with {@link #isBeingHandledByLegacyUrlSupport(String)} | ||
*/ | ||
@Deprecated | ||
public static boolean isFilePath(final String path) { | ||
return ! ( path.startsWith("http:") || path.startsWith("https:") || path.startsWith("ftp:") ); | ||
return !canBeHandledByLegacyUrlSupport(path); | ||
} | ||
|
||
/** | ||
* is this path being handled by one of the legacy SeekableStream types (http(s) / ftp) | ||
* | ||
* @param path a path to check | ||
* @return if the path is not being handled by a FileSystemProvider and it can be read by legacy streams | ||
*/ | ||
public static boolean isBeingHandledByLegacyUrlSupport(final String path){ | ||
return !new HtsPath(path).hasFileSystemProvider() //if we have a provider for it that's what we'll use | ||
&& canBeHandledByLegacyUrlSupport(path); // otherwise we fall back to the special handlers | ||
} | ||
|
||
//is this one of the url types that has legacy htsjdk support built in? | ||
public static boolean canBeHandledByLegacyUrlSupport(final String path) { | ||
return URL_SCHEMES_WITH_LEGACY_SUPPORT.stream().anyMatch(scheme-> path.startsWith(scheme +"://")); | ||
} | ||
|
||
private static class DefaultSeekableStreamFactory implements ISeekableStreamFactory { | ||
|
@@ -79,7 +109,7 @@ public SeekableStream getStreamFor(final String path) throws IOException { | |
} | ||
|
||
/** | ||
* The wrapper will only be applied to the stream if the stream is treated as a {@link java.nio.file.Path} | ||
* The wrapper will only be applied to the stream if the stream is treated as a {@link Path} | ||
* | ||
* This currently means any uri with a scheme that is not http, https, ftp, or file will have the wrapper applied to it | ||
* | ||
|
@@ -89,26 +119,30 @@ public SeekableStream getStreamFor(final String path) throws IOException { | |
@Override | ||
public SeekableStream getStreamFor(final String path, | ||
Function<SeekableByteChannel, SeekableByteChannel> wrapper) throws IOException { | ||
// todo -- add support for SeekableBlockInputStream | ||
|
||
if (path.startsWith("http:") || path.startsWith("https:")) { | ||
final URL url = new URL(path); | ||
return new SeekableHTTPStream(url); | ||
} else if (path.startsWith("ftp:")) { | ||
return new SeekableFTPStream(new URL(path)); | ||
} else if (path.startsWith("file:")) { | ||
try { | ||
// convert to URI in order to obtain a decoded version of the path string suitable | ||
// for use with the File constructor | ||
final String decodedPath = new URI(path).getPath(); | ||
return new SeekableFileStream(new File(decodedPath)); | ||
} catch (java.net.URISyntaxException e) { | ||
throw new IllegalArgumentException(String.format("The input string %s contains a URI scheme but is not a valid URI", path), e); | ||
} | ||
} else if (IOUtil.hasScheme(path)) { | ||
return new SeekablePathStream(IOUtil.getPath(path), wrapper); | ||
return getStreamFor(new HtsPath(path), wrapper); | ||
} | ||
|
||
|
||
/** | ||
* The wrapper will only be applied to the stream if the stream is treated as a non file:// {@link Path} | ||
* | ||
* This has a fall back to htsjdk's built in http and ftp providers if no FileSystemProvder is available for them | ||
* | ||
* @param path an IOPath to be opened | ||
* @param wrapper a wrapper to apply to the stream allowing direct transformations on the byte stream to be applied | ||
* @throws IOException | ||
*/ | ||
public static SeekableStream getStreamFor(final IOPath path, Function<SeekableByteChannel, SeekableByteChannel> wrapper) throws IOException { | ||
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. If there aren't already tests covering |
||
if(path.hasFileSystemProvider()) { | ||
return path.getScheme().equals(FILE_SCHEME) | ||
? new SeekableFileStream(path.toPath().toFile()) //don't apply the wrapper to local files | ||
: new SeekablePathStream(path.toPath(), wrapper); | ||
} else { | ||
return new SeekableFileStream(new File(path)); | ||
return switch(path.getScheme()){ | ||
case HTTP, HTTPS -> new SeekableHTTPStream(new URL(path.getRawInputString())); | ||
case FTP -> new SeekableFTPStream((new URL(path.getRawInputString()))); | ||
default -> throw new TribbleException("Unknown path type. No FileSystemProvider available for " + path.getRawInputString()); | ||
}; | ||
} | ||
} | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See below -- recommend including "://" in these constants to guard against files named after a protocol
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
instead of adding them to the constants which are also used directly compared against getScheme the isHandledBy method now appends '://' to them.