Skip to content

Commit

Permalink
Added support for getting a list of files from a jar directory in Res…
Browse files Browse the repository at this point in the history
…ourceOf.
  • Loading branch information
Vladimir.Shapkin authored and Vladimir.Shapkin committed Jan 27, 2025
1 parent ea5712d commit 08d9555
Show file tree
Hide file tree
Showing 4 changed files with 172 additions and 5 deletions.
16 changes: 16 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,13 @@ SOFTWARE.
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>files</groupId>
<artifactId>test-data</artifactId>
<version>0.0.1</version>
<scope>system</scope>
<systemPath>${basedir}/src/test/resources/test-data-0.0.1.jar</systemPath>
</dependency>
<dependency>
<groupId>com.google.code.findbugs</groupId>
<artifactId>annotations</artifactId>
Expand All @@ -130,6 +137,15 @@ SOFTWARE.
</dependency>
</dependencies>
<build>
<testResources>
<testResource>
<directory>${basedir}/src/test/resources</directory>
<filtering>true</filtering>
<excludes>
<exclude>test-data-0.0.1.jar</exclude>
</excludes>
</testResource>
</testResources>
<plugins>
<plugin>
<groupId>org.pitest</groupId>
Expand Down
97 changes: 93 additions & 4 deletions src/main/java/org/cactoos/io/ResourceOf.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,15 @@

import java.io.IOException;
import java.io.InputStream;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.stream.Collectors;
import org.cactoos.Func;
import org.cactoos.Input;
import org.cactoos.Text;
Expand Down Expand Up @@ -225,10 +234,18 @@ public InputStream stream() throws Exception {
"The \"classloader\" is NULL, which is not allowed"
);
}
InputStream input = this.loader.getResourceAsStream(
this.path.asString()
);
if (input == null) {
final InputStream input;
final String pth = this.path.asString();
final URL resource = this.loader.getResource(pth);
if (pth.endsWith("/")
&& resource != null
&& "jar".equals(resource.getProtocol())
) {
input = new JarDirectoryFileNameStream(resource, pth)
.files();
} else if (resource != null) {
input = resource.openStream();
} else {
if (this.fallback == null) {
throw new IllegalArgumentException(
"The \"fallback\" is NULL, which is not allowed"
Expand All @@ -240,4 +257,76 @@ public InputStream stream() throws Exception {
}
return input;
}

/**
* Class for creating a stream of file names from a directory to a jar.
*
* @since 0.56.2
*/
private static final class JarDirectoryFileNameStream {

/**
* URL of the jar file.
*/
private final URL url;

/**
* Path to the directory in the jar file.
*/
private final String path;

/**
* Ctor.
*
* @param jarurl URL of the jar file.
* @param pth The directory for which we want to get a list of files.
*/
JarDirectoryFileNameStream(final URL jarurl, final String pth) {
this.url = jarurl;
this.path = pth;
}

/**
* Create InputStream of file names from directory to jar.
*
* @return Stream with file names.
* @throws Exception If something goes wrong
*/
public InputStream files() throws Exception {
final List<String> names = new ArrayList<>(2);
try (JarFile jar = new JarFile(this.extract())) {
final Enumeration<JarEntry> entries = jar.entries();
while (entries.hasMoreElements()) {
final JarEntry entry = entries.nextElement();
final String name = entry.getName();
if (this.path.equals(name)) {
continue;
} else if (name.lastIndexOf(this.path) >= 0) {
names.add(name.substring(this.path.length()));
}
}
}
return
new InputStreamOf(
names
.stream()
.collect(
Collectors.joining("\n")
)
.getBytes(StandardCharsets.UTF_8)
);
}

/**
* Extracts the path to a jar file from a URL.
*
* @return Path to jar file.
* @throws URISyntaxException If this URL cannot be converted to a URI.
*/
private String extract() throws URISyntaxException {
final String fullpath = this.url.toURI().getSchemeSpecificPart();
final int idx = fullpath.indexOf("!/");
return fullpath.substring("file:".length(), idx);
}
}
}
64 changes: 63 additions & 1 deletion src/test/java/org/cactoos/io/ResourceOfTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,13 @@
import org.cactoos.Text;
import org.cactoos.bytes.BytesOf;
import org.cactoos.text.FormattedText;
import org.cactoos.text.Split;
import org.cactoos.text.TextOf;
import org.hamcrest.core.IsEqual;
import org.junit.jupiter.api.Test;
import org.llorllale.cactoos.matchers.Assertion;
import org.llorllale.cactoos.matchers.EndsWith;
import org.llorllale.cactoos.matchers.HasValues;
import org.llorllale.cactoos.matchers.StartsWith;
import org.llorllale.cactoos.matchers.Throws;

Expand All @@ -42,7 +44,7 @@
* @since 0.1
* @checkstyle JavadocMethodCheck (500 lines)
*/
@SuppressWarnings("PMD.JUnitTestsShouldIncludeAssert")
@SuppressWarnings({"PMD.JUnitTestsShouldIncludeAssert", "PMD.TooManyMethods"})
final class ResourceOfTest {

@Test
Expand Down Expand Up @@ -113,6 +115,66 @@ void throwsWhenResourceIsAbsent() {
).affirm();
}

@Test
void readTextFromJar() {
new Assertion<>(
"Can't to read file from jar",
new TextOf(
new BytesOf(
new ResourceOf(
"org/cactoos/io/small-text-file.txt",
"the replacement"
)
)
),
new EndsWith("parent directory.")
).affirm();
}

@Test
void readDirectoryFromJar() {
new Assertion<>(
"Unable to read file names from jar directory",
new Split(
new TextOf(
new BytesOf(
new ResourceOf(
"org/cactoos/io/dir/",
"the replacement"
)
)
),
new TextOf("\\n")
),
new HasValues<>(
new TextOf("second-text-file.txt"),
new TextOf("small-file-in-dir.txt")
)
).affirm();
}

@Test
void readDirectory() {
new Assertion<>(
"Unable to read file names from directory",
new Split(
new TextOf(
new BytesOf(
new ResourceOf(
"org/cactoos/",
"the replacement"
)
)
),
new TextOf("\\n")
),
new HasValues<>(
new TextOf("digest-calculation.txt"),
new TextOf("small-text.txt")
)
).affirm();
}

@Test
void acceptsTextAsResourceName() {
new Assertion<>(
Expand Down
Binary file added src/test/resources/test-data-0.0.1.jar
Binary file not shown.

0 comments on commit 08d9555

Please sign in to comment.