-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor: sonarcloud quality gate (#111)
* refactor(S1118): utility classes should not have public constructors * refactor: fail-fast approach while splitting * refactor: adopt java 17 features * refactor: drop unreachable statement * refactor: generic data factory provider * fix: invalid mockito-inline version * refactor: rename test data factory * feat: switch to mixed memory buffer * refactor: command handler + test coverage * test: make path tests os-agnostic * fix: list files sorted by name * test: cover command factory * test: fix new line test output * test: cover no-arg command execution
- Loading branch information
1 parent
d96a07e
commit d97708e
Showing
36 changed files
with
730 additions
and
120 deletions.
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
38 changes: 38 additions & 0 deletions
38
opdf-api/src/test/java/dev/noid/toolbox/opdf/spi/DataFactoryProviderTest.java
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 |
---|---|---|
@@ -0,0 +1,38 @@ | ||
package dev.noid.toolbox.opdf.spi; | ||
|
||
import static dev.noid.toolbox.opdf.spi.DataFactoryProvider.getInstance; | ||
import static org.junit.jupiter.api.Assertions.assertEquals; | ||
import static org.junit.jupiter.api.Assertions.assertThrows; | ||
|
||
import java.lang.reflect.Constructor; | ||
import org.junit.jupiter.api.Test; | ||
|
||
class DataFactoryProviderTest { | ||
|
||
@Test | ||
void lookup_default_merger_factory() { | ||
assertEquals(NoopDataFactory.class, getInstance(DataMergerFactory.class).getClass()); | ||
} | ||
|
||
@Test | ||
void lookup_default_splitter_factory() { | ||
assertEquals(NoopDataFactory.class, getInstance(DataSplitterFactory.class).getClass()); | ||
} | ||
|
||
@Test | ||
void lookup_unknown_data_factory() { | ||
var error = assertThrows(NoClassDefFoundError.class, () -> getInstance(UnknownDataFactory.class)); | ||
assertEquals("Cannot find any implementations of factory class: " + UnknownDataFactory.class, error.getMessage()); | ||
} | ||
|
||
@Test | ||
void prohibit_instance_creation() { | ||
try { | ||
Constructor<DataFactoryProvider> constructor = DataFactoryProvider.class.getDeclaredConstructor(); | ||
constructor.setAccessible(true); | ||
constructor.newInstance(); | ||
} catch (Exception cause) { | ||
assertEquals(UnsupportedOperationException.class, cause.getCause().getClass()); | ||
} | ||
} | ||
} |
17 changes: 17 additions & 0 deletions
17
opdf-api/src/test/java/dev/noid/toolbox/opdf/spi/NoopDataFactory.java
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 |
---|---|---|
@@ -0,0 +1,17 @@ | ||
package dev.noid.toolbox.opdf.spi; | ||
|
||
import dev.noid.toolbox.opdf.api.DataMerger; | ||
import dev.noid.toolbox.opdf.api.DataSplitter; | ||
|
||
public class NoopDataFactory implements DataMergerFactory, DataSplitterFactory { | ||
|
||
@Override | ||
public DataMerger getMerger() { | ||
return (sources, sink) -> {}; | ||
} | ||
|
||
@Override | ||
public DataSplitter getSplitter() { | ||
return (source, sink) -> {}; | ||
} | ||
} |
5 changes: 5 additions & 0 deletions
5
opdf-api/src/test/java/dev/noid/toolbox/opdf/spi/UnknownDataFactory.java
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 |
---|---|---|
@@ -0,0 +1,5 @@ | ||
package dev.noid.toolbox.opdf.spi; | ||
|
||
public interface UnknownDataFactory { | ||
|
||
} |
1 change: 1 addition & 0 deletions
1
opdf-api/src/test/resources/META-INF/services/dev.noid.toolbox.opdf.spi.DataMergerFactory
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 |
---|---|---|
@@ -0,0 +1 @@ | ||
dev.noid.toolbox.opdf.spi.NoopDataFactory |
1 change: 1 addition & 0 deletions
1
opdf-api/src/test/resources/META-INF/services/dev.noid.toolbox.opdf.spi.DataSplitterFactory
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 |
---|---|---|
@@ -0,0 +1 @@ | ||
dev.noid.toolbox.opdf.spi.NoopDataFactory |
Empty file.
33 changes: 33 additions & 0 deletions
33
opdf-cli/src/main/java/dev/noid/toolbox/opdf/cli/CommandFactory.java
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 |
---|---|---|
@@ -0,0 +1,33 @@ | ||
package dev.noid.toolbox.opdf.cli; | ||
|
||
import java.nio.file.Path; | ||
import java.nio.file.Paths; | ||
import java.util.Map; | ||
import java.util.function.Consumer; | ||
import java.util.function.Function; | ||
|
||
class CommandFactory { | ||
|
||
private final Map<String, Function<String[], Runnable>> registry; | ||
|
||
CommandFactory(Consumer<String> stdout) { | ||
this.registry = Map.of( | ||
"help", args -> new HelpCommand(stdout), | ||
"version", args -> new VersionCommand(stdout), | ||
"split", args -> new SplitCommand(getSource(args)), | ||
"merge", args -> new MergeCommand(getSource(args)) | ||
); | ||
} | ||
|
||
public Runnable getCommand(String... args) { | ||
String key = args.length > 0 ? args[0] : "help"; | ||
return registry.getOrDefault(key, registry.get("help")).apply(args); | ||
} | ||
|
||
private Path getSource(String[] args) { | ||
if (args.length < 2) { | ||
throw new IllegalArgumentException("Source path is missing"); | ||
} | ||
return Paths.get(args[1]); | ||
} | ||
} |
28 changes: 28 additions & 0 deletions
28
opdf-cli/src/main/java/dev/noid/toolbox/opdf/cli/HelpCommand.java
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 |
---|---|---|
@@ -0,0 +1,28 @@ | ||
package dev.noid.toolbox.opdf.cli; | ||
|
||
import java.util.function.Consumer; | ||
|
||
class HelpCommand implements Runnable { | ||
|
||
private static final String HELP = """ | ||
Open PDF Tool | ||
Usage: opdf [COMMAND] | ||
Commands: | ||
help Displays help information about the specified command | ||
version Displays version information | ||
merge Merge several PDF files into one | ||
split Split one PDF file into pages | ||
"""; | ||
|
||
private final Consumer<String> stdout; | ||
|
||
HelpCommand(Consumer<String> stdout) { | ||
this.stdout = stdout; | ||
} | ||
|
||
@Override | ||
public void run() { | ||
stdout.accept(HELP); | ||
} | ||
} |
36 changes: 36 additions & 0 deletions
36
opdf-cli/src/main/java/dev/noid/toolbox/opdf/cli/MergeCommand.java
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 |
---|---|---|
@@ -0,0 +1,36 @@ | ||
package dev.noid.toolbox.opdf.cli; | ||
|
||
import dev.noid.toolbox.opdf.api.DataMerger; | ||
import dev.noid.toolbox.opdf.api.DataSink; | ||
import dev.noid.toolbox.opdf.io.FileSink; | ||
import dev.noid.toolbox.opdf.io.FileSource; | ||
import dev.noid.toolbox.opdf.spi.DataFactoryProvider; | ||
import dev.noid.toolbox.opdf.spi.DataMergerFactory; | ||
|
||
import java.nio.file.Files; | ||
import java.nio.file.Path; | ||
import java.util.List; | ||
import java.util.stream.Stream; | ||
|
||
class MergeCommand implements Runnable { | ||
|
||
private final Path sourceDir; | ||
|
||
MergeCommand(Path sourceDir) { | ||
this.sourceDir = sourceDir; | ||
} | ||
|
||
@Override | ||
public void run() { | ||
Path outputFile = sourceDir.resolve("merged.pdf"); | ||
try (Stream<Path> fileStream = Files.list(sourceDir).sorted()) { | ||
List<FileSource> sources = fileStream.map(FileSource::of).toList(); | ||
DataSink sink = FileSink.of(outputFile); | ||
|
||
DataMerger merger = DataFactoryProvider.getInstance(DataMergerFactory.class).getMerger(); | ||
merger.merge(sources, sink); | ||
} catch (Exception cause) { | ||
throw new IllegalArgumentException(cause); | ||
} | ||
} | ||
} |
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 |
---|---|---|
@@ -1,85 +1,8 @@ | ||
package dev.noid.toolbox.opdf.cli; | ||
|
||
import dev.noid.toolbox.opdf.api.DataMerger; | ||
import dev.noid.toolbox.opdf.api.DataSink; | ||
import dev.noid.toolbox.opdf.api.DataSource; | ||
import dev.noid.toolbox.opdf.api.DataSplitter; | ||
import dev.noid.toolbox.opdf.io.FileSink; | ||
import dev.noid.toolbox.opdf.io.FileSource; | ||
import dev.noid.toolbox.opdf.io.FileUtil; | ||
import dev.noid.toolbox.opdf.io.NamingStrategy; | ||
import dev.noid.toolbox.opdf.spi.DataFactoryProvider; | ||
import java.nio.file.Files; | ||
import java.nio.file.Path; | ||
import java.nio.file.Paths; | ||
import java.util.List; | ||
import java.util.stream.Collectors; | ||
import java.util.stream.Stream; | ||
|
||
public class Opdf { | ||
|
||
public static void main(String[] args) { | ||
if (args.length == 0) { | ||
printHelp(); | ||
} else if ("version".equals(args[0])) { | ||
printVersion(); | ||
} else if ("split".equals(args[0])) { | ||
splitDocument(Paths.get(args[1])); | ||
} else if ("merge".equals(args[0])) { | ||
mergeDocuments(Paths.get(args[1])); | ||
} else { | ||
printHelp(); | ||
} | ||
} | ||
|
||
private static void printHelp() { | ||
String help = "Open PDF Tool\n" | ||
+ "\n" | ||
+ "Usage: opdf [COMMAND]\n" | ||
+ "Commands:\n" | ||
+ " help Displays help information about the specified command\n" | ||
+ " version Displays version information\n" | ||
+ " merge Merge several PDF files into one\n" | ||
+ " split Split one PDF file into pages"; | ||
System.out.println(help); | ||
} | ||
|
||
private static void printVersion() { | ||
String version = Opdf.class.getPackage().getImplementationVersion(); | ||
System.out.println(version); | ||
} | ||
|
||
private static void splitDocument(Path sourceFile) { | ||
Path outputDirectory = sourceFile.getParent(); | ||
DataSource source = new FileSource(sourceFile); | ||
DataSink sink = getStreamSink(outputDirectory, sourceFile); | ||
DataSplitter splitter = DataFactoryProvider.getSplitterFactory().getSplitter(); | ||
splitter.split(source, sink); | ||
} | ||
|
||
private static void mergeDocuments(Path sourceDir) { | ||
if (!Files.isDirectory(sourceDir)) { | ||
return; | ||
} | ||
|
||
Path outputFile = sourceDir.resolve("merged.pdf"); | ||
try (Stream<Path> fileStream = Files.list(sourceDir)) { | ||
List<DataSource> sources = fileStream.map(FileSource::new).collect(Collectors.toList()); | ||
DataSink sink = new FileSink(outputFile); | ||
|
||
DataMerger merger = DataFactoryProvider.getMergerFactory().getMerger(); | ||
merger.merge(sources, sink); | ||
} catch (Exception cause) { | ||
throw new IllegalArgumentException(cause); | ||
} | ||
} | ||
|
||
private static DataSink getStreamSink(Path targetDir, Path sourceFile) { | ||
String nameOnly = FileUtil.getNameWithoutExtension(sourceFile); | ||
String filePath = targetDir.resolve(nameOnly).toString(); | ||
String extension = FileUtil.getExtension(sourceFile); | ||
|
||
NamingStrategy naming = NamingStrategy.ordinary(filePath, extension); | ||
return () -> new FileSink(Paths.get(naming.getName())).getWriting(); | ||
new CommandFactory(System.out::println).getCommand(args).run(); | ||
} | ||
} |
41 changes: 41 additions & 0 deletions
41
opdf-cli/src/main/java/dev/noid/toolbox/opdf/cli/SplitCommand.java
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 |
---|---|---|
@@ -0,0 +1,41 @@ | ||
package dev.noid.toolbox.opdf.cli; | ||
|
||
import dev.noid.toolbox.opdf.api.DataSink; | ||
import dev.noid.toolbox.opdf.api.DataSource; | ||
import dev.noid.toolbox.opdf.api.DataSplitter; | ||
import dev.noid.toolbox.opdf.io.FileSink; | ||
import dev.noid.toolbox.opdf.io.FileSource; | ||
import dev.noid.toolbox.opdf.io.FileUtil; | ||
import dev.noid.toolbox.opdf.io.NamingStrategy; | ||
import dev.noid.toolbox.opdf.spi.DataFactoryProvider; | ||
import dev.noid.toolbox.opdf.spi.DataSplitterFactory; | ||
|
||
import java.nio.file.Path; | ||
import java.nio.file.Paths; | ||
|
||
class SplitCommand implements Runnable { | ||
|
||
private final Path sourceFile; | ||
|
||
SplitCommand(Path sourceFile) { | ||
this.sourceFile = sourceFile; | ||
} | ||
|
||
@Override | ||
public void run() { | ||
Path outputDirectory = sourceFile.getParent(); | ||
DataSource source = FileSource.of(sourceFile); | ||
DataSink sink = getStreamSink(outputDirectory, sourceFile); | ||
DataSplitter splitter = DataFactoryProvider.getInstance(DataSplitterFactory.class).getSplitter(); | ||
splitter.split(source, sink); | ||
} | ||
|
||
private DataSink getStreamSink(Path targetDir, Path sourceFile) { | ||
String nameOnly = FileUtil.getNameWithoutExtension(sourceFile); | ||
String filePath = targetDir.resolve(nameOnly).toString(); | ||
String extension = FileUtil.getExtension(sourceFile); | ||
|
||
NamingStrategy naming = NamingStrategy.ordinary(filePath, extension); | ||
return () -> FileSink.of(Paths.get(naming.getName())).getWriting(); | ||
} | ||
} |
22 changes: 22 additions & 0 deletions
22
opdf-cli/src/main/java/dev/noid/toolbox/opdf/cli/VersionCommand.java
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 |
---|---|---|
@@ -0,0 +1,22 @@ | ||
package dev.noid.toolbox.opdf.cli; | ||
|
||
import java.util.Objects; | ||
import java.util.function.Consumer; | ||
|
||
class VersionCommand implements Runnable { | ||
|
||
private final Consumer<String> stdout; | ||
private final String version; | ||
|
||
VersionCommand(Consumer<String> stdout) { | ||
this.stdout = stdout; | ||
|
||
String implVersion = VersionCommand.class.getPackage().getImplementationVersion(); | ||
this.version = Objects.requireNonNullElse(implVersion, "unknown"); | ||
} | ||
|
||
@Override | ||
public void run() { | ||
stdout.accept(version); | ||
} | ||
} |
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.