-
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
Changes from 1 commit
6cdcbd4
b949659
9eca91a
5376f55
652eda2
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 |
---|---|---|
|
@@ -23,12 +23,17 @@ | |
*/ | ||
package htsjdk.samtools.seekablestream; | ||
|
||
import htsjdk.io.HtsPath; | ||
import htsjdk.io.IOPath; | ||
import htsjdk.samtools.util.IOUtil; | ||
import htsjdk.tribble.TribbleException; | ||
|
||
import java.io.File; | ||
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.function.Function; | ||
|
||
/** | ||
|
@@ -61,9 +66,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 #isSpecialCase(String)} | ||
*/ | ||
@Deprecated | ||
public static boolean isFilePath(final String path) { | ||
return ! ( path.startsWith("http:") || path.startsWith("https:") || path.startsWith("ftp:") ); | ||
return !isSpecialCaseUrlType(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 isSpecialCase(final String path){ | ||
return !new HtsPath(path).isPath() //if we have a provider for it that's what we'll use | ||
&& isSpecialCaseUrlType(path); // otherwise we fall back to the special handlers | ||
} | ||
|
||
//is this onee of the url types that has legacy htsjdk support built in? | ||
private static boolean isSpecialCaseUrlType(final String path) { | ||
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.
|
||
return path.startsWith("http:") || path.startsWith("https:") || path.startsWith("ftp:"); | ||
} | ||
|
||
private static class DefaultSeekableStreamFactory implements ISeekableStreamFactory { | ||
|
@@ -79,7 +103,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 +113,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.isPath()) { | ||
return path.getScheme().equals("file") | ||
? new SeekablePathStream(path.toPath()) //don't apply the wrapper to local files | ||
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. Check usages of 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. I switched back to SeekableFileStream although it makes me sad. |
||
: new SeekablePathStream(path.toPath(), wrapper); | ||
} else { | ||
return new SeekableFileStream(new File(path)); | ||
return switch(path.getScheme()){ | ||
case "http", "https" -> new SeekableHTTPStream(new URL(path.getURIString())); | ||
case "ftp" -> new SeekableFTPStream((new URL(path.getURIString()))); | ||
default -> throw new TribbleException("Unknown path type. No FileSystemProvider available for " + path.getRawInputString()); | ||
}; | ||
} | ||
} | ||
|
||
|
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.
Maybe break out out a
hasNIOPlugin()
(or similar) method for thenew HtsPath(path).isPath()
everywhere, for clarity?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.
Or should you be using
hasFileSystemProvider()
instead?