Convert app module to Java (#488)

* app.Program: convert to Java

* app.Main: convert to Java

* app: remove scala dependencies

* parent: remove scala dependencies
This commit is contained in:
Paul Campbell 2020-06-27 18:50:34 +01:00 committed by GitHub
parent 783402f745
commit ee5a831e81
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 112 additions and 190 deletions

View file

@ -45,20 +45,10 @@
<groupId>net.kemitix.thorp</groupId> <groupId>net.kemitix.thorp</groupId>
<artifactId>thorp-uishell</artifactId> <artifactId>thorp-uishell</artifactId>
</dependency> </dependency>
<!-- scala -->
<dependency>
<groupId>org.scala-lang</groupId>
<artifactId>scala-library</artifactId>
</dependency>
</dependencies> </dependencies>
<build> <build>
<plugins> <plugins>
<plugin>
<groupId>net.alchim31.maven</groupId>
<artifactId>scala-maven-plugin</artifactId>
</plugin>
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId> <artifactId>maven-assembly-plugin</artifactId>

View file

@ -0,0 +1,10 @@
package net.kemitix.thorp;
public class Main {
public static void main(String[] args) {
Program.run(args);
System.exit(0);
}
}

View file

@ -0,0 +1,100 @@
package net.kemitix.thorp;
import net.kemitix.thorp.cli.CliArgs;
import net.kemitix.thorp.config.*;
import net.kemitix.thorp.console.Console;
import net.kemitix.thorp.domain.Counters;
import net.kemitix.thorp.domain.RemoteObjects;
import net.kemitix.thorp.domain.StorageEvent;
import net.kemitix.thorp.domain.Terminal;
import net.kemitix.thorp.domain.channel.Channel;
import net.kemitix.thorp.domain.channel.Sink;
import net.kemitix.thorp.lib.Archive;
import net.kemitix.thorp.lib.LocalFileSystem;
import net.kemitix.thorp.lib.UnversionedMirrorArchive;
import net.kemitix.thorp.storage.Storage;
import net.kemitix.thorp.uishell.UIEvent;
import net.kemitix.thorp.uishell.UIShell;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
public interface Program {
String version = "1.1.0-SNAPSHOT";
String versionLabel = String.format("%sThrop v%s%s",
Terminal.white, version, Terminal.reset);
static void run(String[] args) {
try {
ConfigOptions configOptions = CliArgs.parse(args);
Configuration configuration = ConfigurationBuilder.buildConfig(configOptions);
Console.putStrLn(versionLabel);
if (!ConfigQuery.showVersion(configOptions)) {
executeWithUi(configuration);
}
} catch (ConfigValidationException e) {
Console.putStrLn(String.format(
"Configuration error: %s", e.getErrors()));
} catch (IOException e) {
Console.putStrLn(String.format(
"Error loading configuration: %s", e.getMessage()));
} catch (InterruptedException e) {
Console.putStrLn(String.format(
"Program interrupted: %s", e.getMessage()));
}
}
static void executeWithUi(Configuration configuration) throws InterruptedException {
Channel
.<UIEvent>create("ui")
.addListener(UIShell.listener(configuration))
.run(uiSink -> execute(configuration, uiSink))
.start()
.waitForShutdown();
}
static void execute(Configuration configuration, Sink<UIEvent> uiSink) {
try {
uiSink.accept(UIEvent.showValidConfig());
RemoteObjects remoteObjects = Storage.getInstance().list(configuration.bucket, configuration.prefix);
Archive archive = UnversionedMirrorArchive.create();
List<StorageEvent> storageEvents = new ArrayList<>();
storageEvents.addAll(LocalFileSystem.scanCopyUpload(configuration, uiSink, remoteObjects, archive));
storageEvents.addAll(LocalFileSystem.scanDelete(configuration, uiSink, remoteObjects, archive));
Counters counters = countEvents(storageEvents);
uiSink.accept(UIEvent.showSummary(counters));
} catch (InterruptedException e) {
// do nothing
} finally {
Storage.getInstance().shutdown();
}
}
static Counters countEvents(List<StorageEvent> storageEvents) {
AtomicInteger uploads = new AtomicInteger();
AtomicInteger copies = new AtomicInteger();
AtomicInteger deletes = new AtomicInteger();
AtomicInteger errors = new AtomicInteger();
storageEvents.forEach(storageEvent -> {
if (storageEvent instanceof StorageEvent.UploadEvent) {
uploads.incrementAndGet();
} else if (storageEvent instanceof StorageEvent.CopyEvent) {
copies.incrementAndGet();
} else if (storageEvent instanceof StorageEvent.DeleteEvent) {
deletes.incrementAndGet();
} else if (storageEvent instanceof StorageEvent.ErrorEvent) {
errors.incrementAndGet();
}
});
return Counters.empty
.withUploaded(uploads.get())
.withCopied(copies.get())
.withDeleted(deletes.get())
.withErrors(errors.get());
}
}

View file

@ -1,10 +0,0 @@
package net.kemitix.thorp
object Main {
def main(args: Array[String]): Unit = {
Program.run(args.toList)
System.exit(0)
}
}

View file

@ -1,106 +0,0 @@
package net.kemitix.thorp
import net.kemitix.thorp.cli.CliArgs
import net.kemitix.thorp.config._
import net.kemitix.thorp.console._
import net.kemitix.thorp.domain.StorageEvent.{
CopyEvent,
DeleteEvent,
ErrorEvent,
UploadEvent
}
import net.kemitix.thorp.domain.channel.{Channel, Sink}
import net.kemitix.thorp.domain.{Counters, StorageEvent}
import net.kemitix.thorp.lib.{LocalFileSystem, UnversionedMirrorArchive}
import net.kemitix.thorp.storage.Storage
import net.kemitix.thorp.uishell.{UIEvent, UIShell}
import scala.io.AnsiColor.{RESET, WHITE}
import scala.jdk.CollectionConverters._
trait Program {
val version = "1.1.0-SNAPSHOT"
lazy val versionLabel = s"${WHITE}Thorp v$version$RESET"
def run(args: List[String]): Unit = {
val cli = CliArgs.parse(args.toArray)
val config = ConfigurationBuilder.buildConfig(cli)
Console.putStrLn(versionLabel)
if (!showVersion(cli)) {
executeWithUI(config)
}
}
private def showVersion: ConfigOptions => Boolean =
cli => ConfigQuery.showVersion(cli)
private def executeWithUI(configuration: Configuration): Unit = {
Channel
.create("ui")
.addListener(UIShell.listener(configuration))
.run(execute(configuration)(_))
.start()
.waitForShutdown()
}
private def execute(
configuration: Configuration
)(uiSink: Sink[UIEvent]): Unit = {
try {
showValidConfig(uiSink)
val remoteObjects =
fetchRemoteData(configuration, uiSink)
val archive = UnversionedMirrorArchive.create
val storageEvents = LocalFileSystem
.scanCopyUpload(configuration, uiSink, remoteObjects, archive)
val deleteEvents = LocalFileSystem
.scanDelete(configuration, uiSink, remoteObjects, archive)
showSummary(uiSink)(
(storageEvents.asScala ++ deleteEvents.asScala).toList
)
} finally {
Storage.getInstance().shutdown()
}
}
private def showValidConfig(uiSink: Sink[UIEvent]): Unit =
uiSink.accept(UIEvent.showValidConfig)
private def fetchRemoteData(configuration: Configuration,
uiSink: Sink[UIEvent]) = {
val bucket = configuration.bucket
val prefix = configuration.prefix
val objects = Storage.getInstance().list(bucket, prefix)
uiSink.accept(UIEvent.remoteDataFetched(objects.byKey.size))
objects
}
//TODO not called
private def logValidationErrors(throwable: Throwable) =
throwable match {
case validateError: ConfigValidationException =>
validateError.getErrors.asScala
.map(error => Console.putStrLn(s"- $error"))
}
private def showSummary(
uiSink: Sink[UIEvent]
)(events: Seq[StorageEvent]): Unit = {
val counters = events.foldLeft(Counters.empty)(countActivities)
uiSink.accept(UIEvent.showSummary(counters))
}
private def countActivities =
(counters: Counters, s3Action: StorageEvent) => {
s3Action match {
case _: UploadEvent => counters.incrementUploaded()
case _: CopyEvent => counters.incrementCopied()
case _: DeleteEvent => counters.incrementDeleted()
case _: ErrorEvent => counters.incrementErrors()
case _ => counters
}
}
}
object Program extends Program

Binary file not shown.

Before

Width:  |  Height:  |  Size: 177 KiB

After

Width:  |  Height:  |  Size: 190 KiB

View file

@ -66,9 +66,10 @@ public class Terminal {
public static String enableAlternateBuffer = csi + "?1049h"; public static String enableAlternateBuffer = csi + "?1049h";
public static String disableAlternateBuffer = csi + "?1049l"; public static String disableAlternateBuffer = csi + "?1049l";
public static String reset = "\u001B[0m";
public static String red = "\u001B[31m"; public static String red = "\u001B[31m";
public static String green = "\u001B[32m"; public static String green = "\u001B[32m";
public static String reset = "\u001B[0m"; public static String white = "\u001B[37m";
private static Map<Integer, String> getSubBars() { private static Map<Integer, String> getSubBars() {
Map<Integer, String> subBars = new HashMap<>(); Map<Integer, String> subBars = new HashMap<>();

View file

@ -16,10 +16,8 @@
<packaging>pom</packaging> <packaging>pom</packaging>
<properties> <properties>
<scala-maven-plugin.version>4.4.0</scala-maven-plugin.version>
<tiles-maven-plugin.version>2.17</tiles-maven-plugin.version> <tiles-maven-plugin.version>2.17</tiles-maven-plugin.version>
<kemitix-maven-tiles.version>2.7.0</kemitix-maven-tiles.version> <kemitix-maven-tiles.version>2.7.0</kemitix-maven-tiles.version>
<scala-library.version>2.13.3</scala-library.version>
<lombok.version>1.18.12</lombok.version> <lombok.version>1.18.12</lombok.version>
<mon.version>2.2.0</mon.version> <mon.version>2.2.0</mon.version>
<junit.version>5.6.2</junit.version> <junit.version>5.6.2</junit.version>
@ -111,71 +109,10 @@
<artifactId>assertj-core</artifactId> <artifactId>assertj-core</artifactId>
<version>${assertj.version}</version> <version>${assertj.version}</version>
</dependency> </dependency>
<!-- scala - scala -->
<dependency>
<groupId>org.scala-lang</groupId>
<artifactId>scala-library</artifactId>
<version>${scala-library.version}</version>
</dependency>
<!-- scala - command line parsing -->
<dependency>
<groupId>com.github.scopt</groupId>
<artifactId>scopt_2.13</artifactId>
<version>4.0.0-RC2</version>
</dependency>
<!-- scala - test -->
<dependency>
<groupId>org.scalatest</groupId>
<artifactId>scalatest_2.13</artifactId>
<version>3.0.8</version>
</dependency>
<dependency><!-- only used by storage-aws -->
<groupId>org.scalamock</groupId>
<artifactId>scalamock_2.13</artifactId>
<version>4.4.0</version>
</dependency>
</dependencies> </dependencies>
</dependencyManagement> </dependencyManagement>
<build> <build>
<pluginManagement>
<plugins>
<plugin>
<groupId>net.alchim31.maven</groupId>
<artifactId>scala-maven-plugin</artifactId>
<version>${scala-maven-plugin.version}</version>
<configuration>
<args>
<arg>-Ywarn-unused:imports</arg>
<arg>-Xfatal-warnings</arg>
<arg>-feature</arg>
<arg>-deprecation</arg>
<arg>-unchecked</arg>
<arg>-language:postfixOps</arg>
<arg>-language:higherKinds</arg>
</args>
</configuration>
<executions>
<execution>
<id>scala-compile-first</id>
<phase>process-resources</phase>
<goals>
<goal>add-source</goal>
<goal>compile</goal>
</goals>
</execution>
<execution>
<id>scala-test-compile</id>
<phase>process-test-resources</phase>
<goals>
<goal>testCompile</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
<plugins> <plugins>
<plugin> <plugin>
<groupId>io.repaint.maven</groupId> <groupId>io.repaint.maven</groupId>