Skip to content
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

Introduce path formatter #35

Merged
merged 3 commits into from
Feb 5, 2025
Merged
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
34 changes: 32 additions & 2 deletions measurement-provider/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,43 @@
<parent>
<groupId>life.qbic</groupId>
<artifactId>data-download-server</artifactId>
<version>1.0.5</version>
<version>1.0.6</version>
</parent>

<groupId>life.qbic.data-download</groupId>
<artifactId>measurement-provider</artifactId>
<version>1.0.5</version>
<version>1.0.6</version>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>org.spockframework</groupId>
<artifactId>spock-core</artifactId>
<version>2.4-M4-groovy-4.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.groovy</groupId>
<artifactId>groovy-all</artifactId>
<version>4.0.24</version>
<type>pom</type>
<scope>test</scope>
</dependency>
<!-- JUnit Platform for Spock -->
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-launcher</artifactId>
<version>1.9.2</version> <!-- Ensure it's at least 1.7+ -->
<scope>test</scope>
</dependency>

<!-- Optional: For Running Spock with JUnit 5 -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.9.2</version>
<scope>test</scope>
</dependency>
</dependencies>

<build>
<plugins>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
package life.qbic.data_download.measurements.api;

import java.nio.file.InvalidPathException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.regex.Pattern;

/**
* PathFormatter applies filters to a given String value that represents a path.
*
* @since 1.1.0
*/
public class PathFormatter {

private final List<String> filter;

private PathFormatter() {
filter = new ArrayList<>();
}

private PathFormatter(Collection<String> filter) {
this.filter = new ArrayList<>(filter);
}

/**
* Creates a new instance of {@link PathFormatter} with a collection of filter regex expression.
*
* @param filter the terms to filter out
* @return a {@link PathFormatter} instance
* @since 1.1.0
*/
public static PathFormatter with(Collection<String> filter) {
Objects.requireNonNull(filter);
return new PathFormatter(filter);
}

private static String apply(Path p, Collection<String> filter) {
Path result = p.isAbsolute() ? p.getRoot() : Paths.get("");

for (Path part : p) {
if (matchesAny(part.toString(), filter)) {
continue;
}
result = result.resolve(part);
}
return result.toString();
}

private static boolean matchesAny(String s, Collection<String> filter) {
return filter.stream().anyMatch(s::matches);
}

/**
* Applies the configured filter to the provided String.
* <p>
* The provided String is expected to be a valid {@link java.nio.file.Path}, otherwise an
* {@link InvalidPathException} is thrown.
* <p>
* Format iterates through every part of the path and checks them agains the configured filters.
* <p>
* The filter matching works the same as {@link Pattern#matches(String, CharSequence)}.
* <p>
* The resulting String representation of a path will be removed of any matching filter terms.
*
* <pre>
* List<String> filters = Arrays.asList("removeme");
* var formatter = PathFormatter.with(filters);
*
* System.out.println(formatter("/example/removeme/path"));
*
* // Prints out "/example/path"
* </pre>
* <p>
* Format has an implicit check for {@link Path#isAbsolute()} and preserves an absolute or
* relative path.
*
* @param s the String value to format
* @return the formatted new String, after the filter has been applied
* @throws InvalidPathException in case the String is not a valid path
* @since 1.1.0
*/
public String format(String s) throws InvalidPathException {
return apply(Path.of(s), filter);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package life.qbic.data_download.measurement.api

import life.qbic.data_download.measurements.api.PathFormatter
import spock.lang.Specification

class PathFormatterSpec extends Specification {

def "Given a String with a to filtered part, the filtered part must not be part of the resulting String"() {
given:
var filter = Arrays.asList("awesome", "wehaa")

and:
var f = PathFormatter.with(filter)

when:
var result = f.format(input)

then:
result == expected

where:
input | expected
"/my/awesome/path/wehaa" | "/my/path"
"a/relative/wehaa/awesome/path" | "a/relative/path"
}

def "Given a String that contains a UUID-4 in its path, the formatter shall filter it out"() {
given:
var filter = Arrays.asList("^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\$")

and:
var f = PathFormatter.with(filter)

when:
var result = f.format(input)

then:
result == expected

where:
input | expected
"/my/f47ac10b-58cc-4372-a567-0e02b2c3d479/path/" | "/my/path"
"a/relative/f47ac10b-58cc-4372-a567-0e02b2c3d479/path" | "a/relative/path"
}
}
6 changes: 3 additions & 3 deletions openbis-connector/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@
<parent>
<groupId>life.qbic</groupId>
<artifactId>data-download-server</artifactId>
<version>1.0.5</version>
<version>1.0.6</version>
</parent>

<groupId>life.qbic.data-download</groupId>
<artifactId>openbis-connector</artifactId>
<packaging>jar</packaging>
<version>1.0.5</version>
<version>1.0.6</version>

<dependencyManagement>
<dependencies>
Expand Down Expand Up @@ -66,7 +66,7 @@
<dependency>
<groupId>life.qbic.data-download</groupId>
<artifactId>measurement-provider</artifactId>
<version>1.0.5</version>
<version>1.0.6</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,29 @@
import ch.ethz.sis.openbis.generic.dssapi.v3.dto.datasetfile.download.DataSetFileDownload;
import ch.ethz.sis.openbis.generic.dssapi.v3.dto.datasetfile.download.DataSetFileDownloadReader;
import java.io.InputStream;
import java.util.Optional;
import java.util.List;
import java.util.Objects;
import life.qbic.data_download.measurements.api.DataFile;
import life.qbic.data_download.measurements.api.FileInfo;
import life.qbic.data_download.measurements.api.MeasurementDataReader;
import life.qbic.data_download.measurements.api.PathFormatter;

/**
* Reads openbis data streams
*/
public class DatasetFileStreamReaderImpl implements MeasurementDataReader {

private DataSetFileDownloadReader dataSetFileDownloadReader;
private final String ignoredPrefix;

private final PathFormatter formatter;

private static final String UUID_REGEX = "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$";

public DatasetFileStreamReaderImpl(String ignoredPrefix) {
Objects.requireNonNull(ignoredPrefix);
dataSetFileDownloadReader = null;
this.ignoredPrefix = Optional.ofNullable(ignoredPrefix).orElse("");
var filter = List.of(ignoredPrefix, UUID_REGEX);
this.formatter = PathFormatter.with(filter);
}


Expand Down Expand Up @@ -55,7 +62,10 @@ public DataFile nextDataFile() {
.toEpochMilli() : -1;
long lastModifiedMillis = nonNull(dataStore) ? dataStore.getModificationDate().toInstant()
.toEpochMilli() : -1;
FileInfo fileInfo = new FileInfo(fileDownload.getDataSetFile().getPath().replaceFirst(ignoredPrefix, ""),

var cleanedPath = formatter.format(fileDownload.getDataSetFile().getPath());

FileInfo fileInfo = new FileInfo(cleanedPath,
fileDownload.getDataSetFile().getFileLength(),
Integer.toUnsignedLong(fileDownload.getDataSetFile().getChecksumCRC32()),
creationMillis,
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

<groupId>life.qbic</groupId>
<artifactId>data-download-server</artifactId>
<version>1.0.5</version>
<version>1.0.6</version>
<packaging>pom</packaging>


Expand Down
10 changes: 5 additions & 5 deletions rest-api/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@
<parent>
<groupId>life.qbic</groupId>
<artifactId>data-download-server</artifactId>
<version>1.0.5</version>
<version>1.0.6</version>
</parent>

<groupId>life.qbic.data-download</groupId>
<artifactId>rest-server</artifactId>
<version>1.0.5</version>
<version>1.0.6</version>
<packaging>jar</packaging>

<dependencyManagement>
Expand Down Expand Up @@ -65,17 +65,17 @@
<dependency>
<groupId>life.qbic.data-download</groupId>
<artifactId>measurement-provider</artifactId>
<version>1.0.5</version>
<version>1.0.6</version>
</dependency>
<dependency>
<groupId>life.qbic.data-download</groupId>
<artifactId>openbis-connector</artifactId>
<version>1.0.5</version>
<version>1.0.6</version>
</dependency>
<dependency>
<groupId>life.qbic.data-download</groupId>
<artifactId>zip</artifactId>
<version>1.0.5</version>
<version>1.0.6</version>
</dependency>
</dependencies>

Expand Down
2 changes: 1 addition & 1 deletion zip/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<parent>
<groupId>life.qbic</groupId>
<artifactId>data-download-server</artifactId>
<version>1.0.5</version>
<version>1.0.6</version>
</parent>

<groupId>life.qbic.data-download</groupId>
Expand Down