diff --git a/.gitignore b/.gitignore index d211df20..47d79c07 100644 --- a/.gitignore +++ b/.gitignore @@ -33,5 +33,5 @@ hs_err_pid* # Ignore Gradle build output directory .DS_Store -gradle.properties +#gradle.properties xyz.hotchpotch.hogandiff/src/main/resources/xyz/hotchpotch/hogandiff/google/credentials.json diff --git a/.settings/org.eclipse.buildship.core.prefs b/.settings/org.eclipse.buildship.core.prefs index 3f027cfc..808052ef 100644 --- a/.settings/org.eclipse.buildship.core.prefs +++ b/.settings/org.eclipse.buildship.core.prefs @@ -5,7 +5,7 @@ connection.gradle.distribution=GRADLE_DISTRIBUTION(WRAPPER) connection.project.dir= eclipse.preferences.version=1 gradle.user.home= -java.home=C\:/UserLibs/jdk-24.0.1+9-win-x64 +java.home= jvm.arguments= offline.mode=false override.workspace.settings=true diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index b6802de9..00000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "java.configuration.updateBuildConfiguration": "automatic", - "gradle.nestedProjects": true, - "gradle.autoDetect": "on", - "java.jdt.ls.java.home": "C:/UserLibs/jdk-24.0.1+9-win-x64" -} \ No newline at end of file diff --git a/build.gradle b/build.gradle index 834aed10..1c200dec 100644 --- a/build.gradle +++ b/build.gradle @@ -12,7 +12,7 @@ import java.time.format.DateTimeFormatter import java.nio.file.Files import java.nio.file.Path -final def version = '0.26.2' +final def version = '0.27.0' final def timetag = LocalDateTime.now().format(DateTimeFormatter.ofPattern('yyyyMMdd-HHmmss-SSS')) final def baseDir = projectDir.toPath() @@ -83,7 +83,7 @@ task exewrapForWinX64(type: Exec, dependsOn: pickupAndExpandFatJar) { commandLine project['myprop.cmd.exewrap'], '-g', // 直近の LTS-version とする。 - '-t', '21', + '-t', '25', '-i', baseDir.resolve('resources/favicon.ico'), '-v', version, '-V', version, @@ -220,7 +220,7 @@ task checkDependencies(type: Exec, dependsOn: pickupAndExpandFatJar) { commandLine project['myprop.cmd.jdeps'], // 直近の LTS-version とする。 - '--multi-release', 21, + '--multi-release', 25, '--module-path', "${project['myprop.jre.mod.win.x64']};${project['myprop.jfx.sdk.win.x64']};${outputDirTmpJars}", '-s', outputDirTmpJars.resolve("xyz.hotchpotch.hogandiff.jar") } diff --git a/docs/api/versions/latest b/docs/api/versions/latest new file mode 100644 index 00000000..c462f5d5 --- /dev/null +++ b/docs/api/versions/latest @@ -0,0 +1,3 @@ +{ + "version": "0.27.0", +} \ No newline at end of file diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 00000000..b380452a --- /dev/null +++ b/gradle.properties @@ -0,0 +1,17 @@ +org.gradle.java.home=C:/UserLibs/jdk-25+36-win-x64 + +myprop.cmd.exewrap=C:/UserLibs/exewrap-1.6.6/x64/exewrap.exe +myprop.cmd.jlink=C:/UserLibs/jdk-25+36-win-x64/bin/jlink +myprop.cmd.jdeps=C:/UserLibs/jdk-25+36-win-x64/bin/jdeps +myprop.cmd.jpackage=C:/UserLibs/jdk-25+36-win-x64/bin/jpackage + +myprop.userlib=C:/UserLibs +myprop.jre.mod.win.x64=C:/UserLibs/jdk-25+36-jmods-win-x64 +myprop.jre.mod.mac.x64=C:/UserLibs/jdk-25+36-jmods-mac-x64 + +myprop.jfx.mod.win.x64=C:/UserLibs/javafx-jmods-25-win-x64 +myprop.jfx.mod.mac.x64=C:/UserLibs/javafx-jmods-25-mac-x64 + +myprop.jfx.sdk.win.x64=C:/UserLibs/javafx-sdk-25-win-x64/lib +myprop.poi.src=C:/UserLibs/apache-poi-src-5.4.1-20250401 +myprop.log4j.bin=C:/UserLibs/apache-log4j-2.25.2-bin diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index d30212c0..d706aba6 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-9.0.0-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.1.0-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/resources/hogandiff.app/Contents/Info.plist b/resources/hogandiff.app/Contents/Info.plist index 37668c17..e56c3199 100644 --- a/resources/hogandiff.app/Contents/Info.plist +++ b/resources/hogandiff.app/Contents/Info.plist @@ -15,10 +15,10 @@ xyz.hotchpotch.hogandiff CFBundleShortVersionString - 0.26.2 + 0.27.0 CFBundleVersion - 0.26.2 + 0.27.0 CFBundleExecutable Launcher.sh diff --git a/xyz.hotchpotch.hogandiff/.classpath b/xyz.hotchpotch.hogandiff/.classpath index 77bb5e85..00318829 100644 --- a/xyz.hotchpotch.hogandiff/.classpath +++ b/xyz.hotchpotch.hogandiff/.classpath @@ -26,7 +26,7 @@ - + diff --git a/xyz.hotchpotch.hogandiff/.settings/org.eclipse.buildship.core.prefs b/xyz.hotchpotch.hogandiff/.settings/org.eclipse.buildship.core.prefs index 3f027cfc..808052ef 100644 --- a/xyz.hotchpotch.hogandiff/.settings/org.eclipse.buildship.core.prefs +++ b/xyz.hotchpotch.hogandiff/.settings/org.eclipse.buildship.core.prefs @@ -5,7 +5,7 @@ connection.gradle.distribution=GRADLE_DISTRIBUTION(WRAPPER) connection.project.dir= eclipse.preferences.version=1 gradle.user.home= -java.home=C\:/UserLibs/jdk-24.0.1+9-win-x64 +java.home= jvm.arguments= offline.mode=false override.workspace.settings=true diff --git a/xyz.hotchpotch.hogandiff/.settings/org.eclipse.jdt.core.prefs b/xyz.hotchpotch.hogandiff/.settings/org.eclipse.jdt.core.prefs index d1a82289..80136f37 100644 --- a/xyz.hotchpotch.hogandiff/.settings/org.eclipse.jdt.core.prefs +++ b/xyz.hotchpotch.hogandiff/.settings/org.eclipse.jdt.core.prefs @@ -1,4 +1,4 @@ eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.targetPlatform=21 -org.eclipse.jdt.core.compiler.compliance=21 -org.eclipse.jdt.core.compiler.source=21 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=25 +org.eclipse.jdt.core.compiler.compliance=25 +org.eclipse.jdt.core.compiler.source=25 diff --git a/xyz.hotchpotch.hogandiff/build.gradle b/xyz.hotchpotch.hogandiff/build.gradle index 4c5bb365..4bd27847 100644 --- a/xyz.hotchpotch.hogandiff/build.gradle +++ b/xyz.hotchpotch.hogandiff/build.gradle @@ -11,9 +11,9 @@ repositories { dependencies { implementation 'org.apache.poi:poi-ooxml:5.4.1' - implementation 'org.apache.logging.log4j:log4j-core:2.25.1' + implementation 'org.apache.logging.log4j:log4j-core:2.25.2' implementation 'com.google.oauth-client:google-oauth-client-jetty:1.39.0' - implementation 'com.google.apis:google-api-services-drive:v3-rev20250723-2.0.0' + implementation 'com.google.apis:google-api-services-drive:v3-rev20250910-2.0.0' implementation 'com.google.apis:google-api-services-oauth2:v2-rev20200213-2.0.0' implementation 'org.json:json:20250517' implementation 'io.github.cdimascio:dotenv-java:3.2.0' @@ -29,8 +29,8 @@ test { java { // 直近の LTS-version とする。 - sourceCompatibility = JavaVersion.VERSION_21 - targetCompatibility = JavaVersion.VERSION_21 + sourceCompatibility = JavaVersion.VERSION_25 + targetCompatibility = JavaVersion.VERSION_25 } tasks.withType(JavaCompile) { @@ -39,7 +39,7 @@ tasks.withType(JavaCompile) { javafx { // 直近の LTS-version とする。 - version = 21 + version = 25 modules = [ 'javafx.controls', 'javafx.fxml' ] } diff --git a/xyz.hotchpotch.hogandiff/gradle.properties b/xyz.hotchpotch.hogandiff/gradle.properties index 82f06bac..8658d4e3 100644 --- a/xyz.hotchpotch.hogandiff/gradle.properties +++ b/xyz.hotchpotch.hogandiff/gradle.properties @@ -1 +1 @@ -org.gradle.java.home=C:/UserLibs/jdk-24.0.2+12-win-x64 +org.gradle.java.home=C:/UserLibs/jdk-25+36-win-x64 diff --git a/xyz.hotchpotch.hogandiff/gradle/wrapper/gradle-wrapper.properties b/xyz.hotchpotch.hogandiff/gradle/wrapper/gradle-wrapper.properties index d30212c0..d706aba6 100644 --- a/xyz.hotchpotch.hogandiff/gradle/wrapper/gradle-wrapper.properties +++ b/xyz.hotchpotch.hogandiff/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-9.0.0-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.1.0-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git "a/xyz.hotchpotch.hogandiff/messages.properties\347\256\241\347\220\206.xlsx" "b/xyz.hotchpotch.hogandiff/messages.properties\347\256\241\347\220\206.xlsx" index 72cea35d..33d0091a 100644 Binary files "a/xyz.hotchpotch.hogandiff/messages.properties\347\256\241\347\220\206.xlsx" and "b/xyz.hotchpotch.hogandiff/messages.properties\347\256\241\347\220\206.xlsx" differ diff --git a/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/AppMain.java b/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/AppMain.java index 0f87bb72..799de3d1 100644 --- a/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/AppMain.java +++ b/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/AppMain.java @@ -1,10 +1,5 @@ package xyz.hotchpotch.hogandiff; -import java.awt.Desktop; -import java.io.IOException; -import java.net.URI; -import java.util.UUID; - import org.apache.poi.openxml4j.util.ZipSecureFile; import javafx.application.Application; @@ -25,9 +20,6 @@ public class AppMain extends Application { // [static members] ******************************************************** - /** このアプリケーションのバージョン */ - public static final String VERSION = "v0.26.2"; - /** このアプリケーションのドメイン(xyz.hotchpotch.hogandiff) */ public static final String APP_DOMAIN = AppMain.class.getPackageName(); @@ -53,7 +45,8 @@ public class AppMain extends Application { /** * このアプリケーションのエントリポイントです。
* - * @param args アプリケーション実行時引数 + * @param args + * アプリケーション実行時引数 */ public static void main(String[] args) { appResource.reflectArgs(args); @@ -70,7 +63,7 @@ public static void main(String[] args) { public void start(Stage primaryStage) throws Exception { stage = primaryStage; - announceNewFeature(); + VersionMaster.announceNewFeature1(); // Zip bomb対策の制限の緩和。規定値の0.01から0.001に変更する。 // いささか乱暴ではあるものの、ファイルを開く都度ではなくここで一括で設定してしまう。 @@ -91,7 +84,7 @@ public void start(Stage primaryStage) throws Exception { primaryStage.setTitle( appResource.get().getString("AppMain.010") + " - " - + VERSION); + + VersionMaster.APP_VERSION); primaryStage.setMinHeight( settings.get(SettingKeys.SHOW_SETTINGS) @@ -108,21 +101,22 @@ public void start(Stage primaryStage) throws Exception { if (settings.containsKey(SettingKeys.STAGE_MAXIMIZED)) { primaryStage.setMaximized(settings.get(SettingKeys.STAGE_MAXIMIZED)); } - primaryStage.heightProperty().addListener((target, oldValue, newValue) -> { + primaryStage.heightProperty().addListener((_, _, newValue) -> { if (!primaryStage.isMaximized()) { appResource.changeSetting(SettingKeys.STAGE_HEIGHT, (Double) newValue); } }); - primaryStage.widthProperty().addListener((target, oldValue, newValue) -> { + primaryStage.widthProperty().addListener((_, _, newValue) -> { if (!primaryStage.isMaximized()) { appResource.changeSetting(SettingKeys.STAGE_WIDTH, (Double) newValue); } }); - primaryStage.maximizedProperty().addListener((target, oldValue, newValue) -> { + primaryStage.maximizedProperty().addListener((_, _, newValue) -> { appResource.changeSetting(SettingKeys.STAGE_MAXIMIZED, newValue); }); primaryStage.show(); + VersionMaster.announceNewFeature2(); MainController controller = loader.getController(); if (controller.isReady().getValue()) { @@ -130,32 +124,4 @@ public void start(Stage primaryStage) throws Exception { controller.execute(); } } - - /** - * ユーザーが現在のバージョンを初めて起動した際の処理を行います。
- */ - private void announceNewFeature() { - // UUIDが未採番の場合は採番する。 - UUID uuid = appResource.settings().get(SettingKeys.CLIENT_UUID); - if (uuid == null) { - appResource.changeSetting(SettingKeys.CLIENT_UUID, UUID.randomUUID()); - } - - // 前回までの利用Versionを調べ、新バージョンの初回起動の場合は新バージョンに応じた処理を行う。 - String prevVersion = appResource.settings().get(SettingKeys.APP_VERSION); - if (!VERSION.equals(prevVersion)) { - - assert VERSION.equals("v0.26.2"); - // v0.26.2 では次を行う。 - // ・新機能紹介ページの表示 - - try { - Desktop.getDesktop().browse(URI.create("https://hogandiff.hotchpotch.xyz/releasenotes/v0-26-2/")); - } catch (IOException e) { - e.printStackTrace(); - // nop - } - appResource.changeSetting(SettingKeys.APP_VERSION, VERSION); - } - } } diff --git a/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/AppResource.java b/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/AppResource.java index ab6ab5fd..e44a1a5c 100644 --- a/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/AppResource.java +++ b/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/AppResource.java @@ -53,7 +53,7 @@ public class AppResource { } /** プロパティファイルの相対パス */ - private static Path APP_PROP_PATH = USER_HOME != null + public static Path APP_PROP_PATH = USER_HOME != null ? USER_HOME.resolve("hogandiff.properties") : null; diff --git a/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/SettingKeys.java b/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/SettingKeys.java index facb230d..a6f684ff 100644 --- a/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/SettingKeys.java +++ b/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/SettingKeys.java @@ -3,10 +3,10 @@ import java.awt.Color; import java.lang.reflect.Modifier; import java.nio.file.Path; +import java.time.Instant; import java.util.Locale; import java.util.Map; import java.util.Set; -import java.util.UUID; import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -28,19 +28,11 @@ public class SettingKeys { // [static members] ******************************************************** private static Function decodeNotSupported(String msg) { - return str -> { + return _ -> { throw new UnsupportedOperationException(msg); }; } - /** クライアント上で生成されたUUID */ - public static final Key CLIENT_UUID = new Key<>( - "client.uuid", - () -> null, - UUID::toString, - UUID::fromString, - true); - /** このアプリケーションの実行したことのあるバージョン */ public static final Key APP_VERSION = new Key<>( "application.appVersion", @@ -117,7 +109,7 @@ private static Function decodeNotSupported(String msg) { public static final Key> CURR_READ_PASSWORDS = new Key<>( "current.readPasswords", () -> Map.of(), - readPasswords -> "*****", + _ -> "*****", decodeNotSupported("cannot decode."), false); @@ -316,6 +308,30 @@ private static Function decodeNotSupported(String msg) { Boolean::valueOf, true); + /** 起動時に新規バージョンの有無を確認するか */ + public static final Key CHECK_UPDATES = new Key<>( + "application.checkUpdates", + () -> false, + String::valueOf, + Boolean::valueOf, + true); + + /** 新バージョン有無の最終チェック日時 */ + public static final Key LAST_CHECK_UPDATES = new Key<>( + "application.lastCheckUpdates", + () -> null, + Instant::toString, + Instant::parse, + true); + + /** 新バージョン有無チェックの最短間隔(時間) */ + public static final Key CHECK_UPDATES_INTERVAL_MINUTES = new Key<>( + "application.checkUpdatesIntervalHours", + () -> 120, + String::valueOf, + Integer::valueOf, + false); + /** 全ての定義済み設定項目を含むセット */ // Collectors#toSet は現在の実装では immutable set を返すが // 保証されないということなので、一応 Set#copyOf でラップしておく。 diff --git a/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/VersionMaster.java b/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/VersionMaster.java new file mode 100644 index 00000000..695322af --- /dev/null +++ b/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/VersionMaster.java @@ -0,0 +1,108 @@ +package xyz.hotchpotch.hogandiff; + +import java.awt.Desktop; +import java.io.IOException; +import java.net.URI; +import java.util.function.Function; + +import javafx.application.Platform; +import javafx.scene.control.Button; + +/** + * このアプリケーションのバージョン情報を管理するクラスです。
+ * + * @author nmby + */ +public class VersionMaster { + + // [static members] ******************************************************** + + private static final AppResource ar = AppMain.appResource; + + /** このアプリケーションのバージョン */ + public static final String APP_VERSION = "v0.27.0"; + + /** v0.27.0新機能アナウンス機能用変数 */ + public static Button for_v0_27_0; + + /** + * このアプリの現在のバージョンと指定されたバージョンを比較します。
+ * + * @param comparisonTarget 比較対象のバージョン + * @return 現在のバージョンの方が新しい場合は {@code 1}、同じ場合は {@code 0}、古い場合は {@code -1} + */ + public static int compareVersion(String comparisonTarget) { + Function toVersionNumbers = (v) -> { + String[] parts = v.replace("v", "").split("\\."); + if (parts.length != 3) { + throw new IllegalArgumentException("Invalid version string: " + v); + } + int[] numbers = new int[parts.length]; + for (int i = 0; i < parts.length; i++) { + numbers[i] = Integer.parseInt(parts[i]); + } + return numbers; + }; + + int[] target = toVersionNumbers.apply(comparisonTarget); + int[] me = toVersionNumbers.apply(APP_VERSION); + for (int i = 0; i < target.length; i++) { + if (me[i] > target[i]) { + return 1; + } else if (me[i] < target[i]) { + return -1; + } + } + return 0; + } + + /** + * ユーザーが現在のバージョンを初めて起動した際の処理を行います。
+ */ + public static void announceNewFeature1() { + // 前回までの利用Versionを調べ、新バージョンの初回起動の場合は新バージョンに応じた処理を行う。 + String prevVersion = ar.settings().get(SettingKeys.APP_VERSION); + if (prevVersion == null || compareVersion(prevVersion) > 0) { + + assert APP_VERSION.equals("v0.27.0"); + // v0.27.0 では次を行う。 + // ●設定エリアの強制展開 + // ・詳細設定ダイアログの強制表示 + // ・新機能紹介ページの表示 + ar.changeSetting(SettingKeys.SHOW_SETTINGS, true); + } + } + + /** + * ユーザーが現在のバージョンを初めて起動した際の処理を行います。
+ */ + public static void announceNewFeature2() { + // 前回までの利用Versionを調べ、新バージョンの初回起動の場合は新バージョンに応じた処理を行う。 + String prevVersion = ar.settings().get(SettingKeys.APP_VERSION); + if (prevVersion == null || compareVersion(prevVersion) > 0) { + + assert APP_VERSION.equals("v0.27.0"); + // v0.27.0 では次を行う。 + // ・設定エリアの強制展開 + // ●詳細設定ダイアログの強制表示 + // ●新機能紹介ページの表示 + + try { + if (for_v0_27_0 != null) { + Platform.runLater(() -> for_v0_27_0.fire()); + } + Desktop.getDesktop().browse(URI.create("https://hogandiff.hotchpotch.xyz/releasenotes/v0-27-0/")); + + } catch (IOException e) { + e.printStackTrace(); + // nop + } + ar.changeSetting(SettingKeys.APP_VERSION, APP_VERSION); + } + } + + // [instance members] ****************************************************** + + private VersionMaster() { + } +} diff --git a/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/core/MinimumEditDistanceMatcher.java b/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/core/MinimumEditDistanceMatcher.java index 2cf43f05..45024fe3 100644 --- a/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/core/MinimumEditDistanceMatcher.java +++ b/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/core/MinimumEditDistanceMatcher.java @@ -13,7 +13,8 @@ * 文字列(文字を要素とするリスト)同士のマッチングだけでなく、 * 任意の型の要素のリスト同士のマッチングに利用することができます。
* - * @param リストの要素の型 + * @param + * リストの要素の型 * @author nmby */ /*package*/ class MinimumEditDistanceMatcher extends MatcherBase { @@ -64,7 +65,8 @@ private static sealed interface ComeFrom /** * エディットグラフの上から遷移してきたことを表します。 * - * @param prev 遷移元ノード + * @param prev + * 遷移元ノード */ static record Upper(ComeFrom prev) implements ComeFrom { } @@ -72,7 +74,8 @@ static record Upper(ComeFrom prev) implements ComeFrom { /** * エディットグラフの左から遷移してきたことを表します。 * - * @param prev 遷移元ノード + * @param prev + * 遷移元ノード */ static record Left(ComeFrom prev) implements ComeFrom { } @@ -80,7 +83,8 @@ static record Left(ComeFrom prev) implements ComeFrom { /** * エディットグラフの左上から遷移してきたことを表します。 * - * @param prev 遷移元ノード + * @param prev + * 遷移元ノード */ static record UpperLeft(ComeFrom prev) implements ComeFrom { } @@ -89,9 +93,9 @@ static record UpperLeft(ComeFrom prev) implements ComeFrom { default Direction direction() { return switch (this) { - case Upper from -> Direction.FROM_UPPER; - case Left from -> Direction.FROM_LEFT; - case UpperLeft from -> Direction.FROM_UPPER_LEFT; + case Upper _ -> Direction.FROM_UPPER; + case Left _ -> Direction.FROM_LEFT; + case UpperLeft _ -> Direction.FROM_UPPER_LEFT; }; } @@ -103,8 +107,10 @@ default Direction direction() { /** * コンストラクタ * - * @param gapEvaluator 余剰評価関数 - * @param diffEvaluator 差分評価関数 + * @param gapEvaluator + * 余剰評価関数 + * @param diffEvaluator + * 差分評価関数 */ /*package*/ MinimumEditDistanceMatcher( ToIntFunction gapEvaluator, @@ -119,9 +125,12 @@ default Direction direction() { /** * コンストラクタ * - * @param gapEvaluatorA 比較対象Aに適用する余剰評価関数 - * @param gapEvaluatorB 比較対象Bに適用する余剰評価関数 - * @param diffEvaluator 差分評価関数 + * @param gapEvaluatorA + * 比較対象Aに適用する余剰評価関数 + * @param gapEvaluatorB + * 比較対象Bに適用する余剰評価関数 + * @param diffEvaluator + * 差分評価関数 */ /*package*/ MinimumEditDistanceMatcher( ToIntFunction gapEvaluatorA, diff --git a/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/core/StringDiffUtil.java b/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/core/StringDiffUtil.java index df0adc67..1439397d 100644 --- a/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/core/StringDiffUtil.java +++ b/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/core/StringDiffUtil.java @@ -23,7 +23,7 @@ public class StringDiffUtil { // [static members] ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ private static final Matcher codeMatcher = new MinimumEditDistanceMatcher<>( - x -> 1, + _ -> 1, (x, y) -> x.equals(y) ? 0 : 3); /** @@ -31,10 +31,13 @@ public class StringDiffUtil { * 一文字の挿入と削除はそれぞれ距離1と評価します。 * 一文字の置換は削除+挿入とみなし、従って距離2と評価します。
* - * @param str1 文字列1 - * @param str2 文字列2 + * @param str1 + * 文字列1 + * @param str2 + * 文字列2 * @return 2つの文字列間のレーベンシュタイン距離 - * @throws NullPointerException パラメータが {@code null} の場合 + * @throws NullPointerException + * パラメータが {@code null} の場合 */ public static int levenshteinDistance(String str1, String str2) { Objects.requireNonNull(str1); diff --git a/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/gui/MainController.java b/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/gui/MainController.java index ea8b0912..67137c57 100644 --- a/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/gui/MainController.java +++ b/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/gui/MainController.java @@ -118,7 +118,7 @@ public void initialize() { .and(row3Pane.isReady()) .and(row4Pane.isReady())); - row3Pane.showSettings().addListener((target, oldValue, newValue) -> { + row3Pane.showSettings().addListener((_, _, newValue) -> { if (newValue) { row4Pane.setVisible2(true); AppMain.stage.setHeight(AppMain.stage.getHeight() + row4Pane.originalHeight()); @@ -130,19 +130,22 @@ public void initialize() { } }); - menuProp.addListener((target, oldVal, newVal) -> updateActiveComparison()); - sheetNamePropPair.a().addListener((target, oldVal, newVal) -> updateActiveComparison()); - sheetNamePropPair.b().addListener((target, oldVal, newVal) -> updateActiveComparison()); - bookInfoPropPair.a().addListener((target, oldVal, newVal) -> updateActiveComparison()); - bookInfoPropPair.b().addListener((target, oldVal, newVal) -> updateActiveComparison()); - dirInfoPropPair.a().addListener((target, oldVal, newVal) -> updateActiveComparison()); - dirInfoPropPair.b().addListener((target, oldVal, newVal) -> updateActiveComparison()); + menuProp.addListener((_, _, _) -> updateActiveComparison()); + sheetNamePropPair.a().addListener((_, _, _) -> updateActiveComparison()); + sheetNamePropPair.b().addListener((_, _, _) -> updateActiveComparison()); + bookInfoPropPair.a().addListener((_, _, _) -> updateActiveComparison()); + bookInfoPropPair.b().addListener((_, _, _) -> updateActiveComparison()); + dirInfoPropPair.a().addListener((_, _, _) -> updateActiveComparison()); + dirInfoPropPair.b().addListener((_, _, _) -> updateActiveComparison()); // 3.初期値の設定 row4Pane.setVisible2(row3Pane.showSettings().getValue()); // 4.値変更時のイベントハンドラの設定 // nop + + // 5.その他 + UpdateChecker.execute(false); } /** @@ -286,7 +289,8 @@ private Stream bookPathStream(PairingInfoDirs dirComparison) { /** * 比較処理を実行します。
* - * @throws IllegalStateException 必要な設定がなされておらず実行できない場合 + * @throws IllegalStateException + * 必要な設定がなされておらず実行できない場合 */ public void execute() { if (!isReady.getValue()) { @@ -322,7 +326,7 @@ public void execute() { currentTask = menu.getTask(ar.settings()); row3Pane.bind(currentTask); - currentTask.setOnSucceeded(event -> { + currentTask.setOnSucceeded(_ -> { row3Pane.unbind(); alertPasswordUnlocked(); @@ -334,7 +338,7 @@ public void execute() { } }); - currentTask.setOnFailed(event -> { + currentTask.setOnFailed(_ -> { Throwable e = currentTask.getException(); e.printStackTrace(); row3Pane.unbind(); diff --git a/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/gui/UIUtil.java b/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/gui/UIUtil.java index c17f880a..8787d0a5 100644 --- a/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/gui/UIUtil.java +++ b/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/gui/UIUtil.java @@ -26,9 +26,11 @@ public class UIUtil { /** * 指定されたURLを開くハイパーリンクを生成します。
* - * @param url URL + * @param url + * URL * @return ハイパーリンク - * @throws NullPointerException 引数がnullの場合 + * @throws NullPointerException + * 引数がnullの場合 */ public static Hyperlink createHyperlink(String url) { Objects.requireNonNull(url); @@ -41,15 +43,18 @@ public static Hyperlink createHyperlink(String url) { /** * 指定されたハイパーリンクに、指定されたURLを開くアクションを設定します。
* - * @param link ハイパーリンク - * @param url URL - * @throws NullPointerException 引数がnullの場合 + * @param link + * ハイパーリンク + * @param url + * URL + * @throws NullPointerException + * 引数がnullの場合 */ public static void setupHyperlink(Hyperlink link, String url) { Objects.requireNonNull(link); Objects.requireNonNull(url); - link.setOnAction(event -> { + link.setOnAction(_ -> { try { Desktop.getDesktop().browse(URI.create(url)); } catch (IOException e) { diff --git a/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/gui/UpdateChecker.java b/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/gui/UpdateChecker.java new file mode 100644 index 00000000..83dc67b6 --- /dev/null +++ b/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/gui/UpdateChecker.java @@ -0,0 +1,98 @@ +package xyz.hotchpotch.hogandiff.gui; + +import java.time.Instant; +import java.time.temporal.ChronoUnit; +import java.util.ResourceBundle; +import java.util.concurrent.CompletableFuture; + +import javafx.application.Platform; +import javafx.scene.control.Alert; +import javafx.scene.control.Alert.AlertType; +import javafx.scene.control.ButtonType; +import javafx.scene.control.Hyperlink; +import javafx.scene.control.Label; +import javafx.scene.layout.VBox; +import xyz.hotchpotch.hogandiff.AppMain; +import xyz.hotchpotch.hogandiff.AppResource; +import xyz.hotchpotch.hogandiff.SettingKeys; +import xyz.hotchpotch.hogandiff.VersionMaster; +import xyz.hotchpotch.hogandiff.util.NetUtil; + +/** + * このアプリケーションの更新チェック機能を提供します。
+ * + * @author nmby + */ +public class UpdateChecker { + + // [static members] ******************************************************** + + private static final AppResource ar = AppMain.appResource; + private static final ResourceBundle rb = ar.get(); + + /** + * 更新チェックを実行します。
+ * {@code force} に {@code true} が指定されている場合は、強制的にチェックします。
+ * {@code force} に {@code false} が指定されている場合は、 + * ユーザーが更新チェックを無効にしている場合、過去数時間以内にチェックしている場合はスキップします。
+ * + * @param force 強制的にチェックする場合は {@code true} + */ + public static void execute(boolean force) { + UpdateChecker checker = new UpdateChecker(); + checker.checkUpdate(force); + } + + // [instance members] ****************************************************** + + private UpdateChecker() { + } + + private void checkUpdate(boolean force) { + if (!force) { + if (!ar.settings().get(SettingKeys.CHECK_UPDATES)) { + return; + } + + Instant lastCheckAt = ar.settings().get(SettingKeys.LAST_CHECK_UPDATES); + int interval = ar.settings().get(SettingKeys.CHECK_UPDATES_INTERVAL_MINUTES); + if (lastCheckAt != null && Instant.now().isBefore(lastCheckAt.plus(interval, ChronoUnit.MINUTES))) { + return; + } + } + + CompletableFuture + .supplyAsync(() -> NetUtil.getAsJson("https://nmby.github.io/hogandiff4/api/versions/latest")) + .thenAccept(json -> { + String latestVersion = json.getString("version"); + if (VersionMaster.compareVersion(latestVersion) < 0) { + Platform.runLater(() -> { + Hyperlink link = UIUtil.createHyperlink(AppMain.WEB_URL); + VBox content = new VBox(10); + content.getChildren().addAll( + new Label(rb.getString("gui.UpdateChecker.020") + .formatted(VersionMaster.APP_VERSION, "v" + latestVersion)), + link); + Alert alert = new Alert(Alert.AlertType.INFORMATION); + alert.setTitle(rb.getString("AppMain.010")); + alert.setHeaderText(rb.getString("gui.UpdateChecker.010")); + alert.getDialogPane().setContent(content); + alert.showAndWait(); + }); + } else if (force) { + Platform.runLater(() -> { + new Alert( + AlertType.INFORMATION, + rb.getString("gui.UpdateChecker.030").formatted(VersionMaster.APP_VERSION), + ButtonType.OK) + .showAndWait(); + }); + } + ar.changeSetting(SettingKeys.LAST_CHECK_UPDATES, Instant.now()); + }) + .exceptionally(throwable -> { + throwable.printStackTrace(); + return null; + }); + } +} diff --git a/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/gui/components/EditComparisonPane.java b/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/gui/components/EditComparisonPane.java index 707ba6f4..30ffcff3 100644 --- a/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/gui/components/EditComparisonPane.java +++ b/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/gui/components/EditComparisonPane.java @@ -45,7 +45,8 @@ public class EditComparisonPane extends AnchorPane implements ChildController { /** * コンストラクタ
* - * @throws IOException FXMLファイルの読み込みに失敗した場合 + * @throws IOException + * FXMLファイルの読み込みに失敗した場合 */ public EditComparisonPane() throws IOException { FXMLLoader loader = new FXMLLoader(getClass().getResource("EditComparisonPane.fxml"), rb); @@ -66,7 +67,7 @@ public void init(MainController parent, Object... param) { parent.menuProp, parent.isReady())); // 2.項目ごとの各種設定 - editComparisonButton.setOnAction(event -> editComparison()); + editComparisonButton.setOnAction(_ -> editComparison()); // 3.初期値の設定 // nop diff --git a/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/gui/components/ExecutePane.java b/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/gui/components/ExecutePane.java index 25115703..60f262ba 100644 --- a/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/gui/components/ExecutePane.java +++ b/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/gui/components/ExecutePane.java @@ -33,7 +33,8 @@ public class ExecutePane extends AnchorPane implements ChildController { /** * コンストラクタ
* - * @throws IOException FXMLファイルの読み込みに失敗した場合 + * @throws IOException + * FXMLファイルの読み込みに失敗した場合 */ public ExecutePane() throws IOException { FXMLLoader loader = new FXMLLoader(getClass().getResource("ExecutePane.fxml"), rb); @@ -51,7 +52,7 @@ public void init(MainController parent, Object... param) { executeButton.disableProperty().bind(parent.isReady().not()); // 2.項目ごとの各種設定 - executeButton.setOnAction(event -> parent.execute()); + executeButton.setOnAction(_ -> parent.execute()); // 3.初期値の設定 // nop diff --git a/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/gui/components/GooglePane.java b/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/gui/components/GooglePane.java index bb8c9960..1eca4021 100644 --- a/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/gui/components/GooglePane.java +++ b/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/gui/components/GooglePane.java @@ -60,7 +60,8 @@ public class GooglePane extends HBox implements ChildController { /** * コンストラクタ
* - * @throws IOException FXMLファイルの読み込みに失敗した場合 + * @throws IOException + * FXMLファイルの読み込みに失敗した場合 */ public GooglePane() throws IOException { FXMLLoader loader = new FXMLLoader(getClass().getResource("GooglePane.fxml"), rb); @@ -108,14 +109,14 @@ public void init(MainController parent, Object... param) { }, parent.googleCredential)); - connectGoogleButton.setOnAction(event -> { + connectGoogleButton.setOnAction(_ -> { Task connectTask = new ConnectGoogleTask(parent.googleCredential); Thread connectThread = new Thread(connectTask); connectThread.setDaemon(true); connectThread.start(); }); - disconnectGoogleButton.setOnAction(event -> { + disconnectGoogleButton.setOnAction(_ -> { Optional result = new Alert( AlertType.CONFIRMATION, rb.getString("gui.component.GooglePane.010")) @@ -158,12 +159,14 @@ public void init(MainController parent, Object... param) { }); // 3.初期値の設定 - new Thread(() -> { + Thread asyncInitGoogleTask = new Thread(() -> { GoogleCredential credential = GoogleCredential.get(false); Platform.runLater(() -> { parent.googleCredential.setValue(credential); }); - }).start(); + }); + asyncInitGoogleTask.setDaemon(true); + asyncInitGoogleTask.start(); // 4.値変更時のイベントハンドラの設定 // nop diff --git a/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/gui/components/MenuPane.java b/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/gui/components/MenuPane.java index b09d2b8c..1ef6f682 100644 --- a/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/gui/components/MenuPane.java +++ b/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/gui/components/MenuPane.java @@ -54,7 +54,8 @@ public class MenuPane extends HBox implements ChildController { /** * コンストラクタ
* - * @throws IOException FXMLファイルの読み込みに失敗した場合 + * @throws IOException + * FXMLファイルの読み込みに失敗した場合 */ public MenuPane() throws IOException { FXMLLoader loader = new FXMLLoader(getClass().getResource("MenuPane.fxml"), rb); @@ -95,10 +96,10 @@ public void init(MainController parent, Object... param) { ar.settings().get(SettingKeys.COMPARE_DIRS_RECURSIVELY)); // 4.値変更時のイベントハンドラの設定 - parent.menuProp.addListener((target, oldValue, newValue) -> ar.changeSetting(SettingKeys.CURR_MENU, newValue)); + parent.menuProp.addListener((_, _, newValue) -> ar.changeSetting(SettingKeys.CURR_MENU, newValue)); recursivelyCheckBox.selectedProperty() - .addListener((target, oldValue, newValue) -> ar.changeSetting( + .addListener((_, _, newValue) -> ar.changeSetting( SettingKeys.COMPARE_DIRS_RECURSIVELY, newValue)); } diff --git a/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/gui/components/ReportingPane.java b/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/gui/components/ReportingPane.java index be519cef..0e53cc8e 100644 --- a/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/gui/components/ReportingPane.java +++ b/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/gui/components/ReportingPane.java @@ -50,7 +50,8 @@ public class ReportingPane extends VBox implements ChildController { /** * コンストラクタ
* - * @throws IOException FXMLファイルの読み込みに失敗した場合 + * @throws IOException + * FXMLファイルの読み込みに失敗した場合 */ public ReportingPane() throws IOException { FXMLLoader loader = new FXMLLoader(getClass().getResource("ReportingPane.fxml"), rb); @@ -91,8 +92,10 @@ public void init(MainController parent, Object... param) { /** * このコンポーネントとタスクをバインドします。
* - * @param task タスク - * @throws NullPointerException パラメータが {@code null} の場合 + * @param task + * タスク + * @throws NullPointerException + * パラメータが {@code null} の場合 */ public void bind(Task task) { Objects.requireNonNull(task); @@ -107,8 +110,8 @@ public void bind(Task task) { .findAny() .ifPresent(bar -> { scrollBar = bar; - reportingTextArea.textProperty().addListener((t, o, n) -> bar.setValue(bar.getMax())); - bar.valueProperty().addListener((target, oldValue, newValue) -> { + reportingTextArea.textProperty().addListener((_, _, _) -> bar.setValue(bar.getMax())); + bar.valueProperty().addListener((_, oldValue, newValue) -> { if (newValue.doubleValue() == 0d && oldValue.doubleValue() == bar.getMax() && !bar.pressedProperty().get() diff --git a/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/gui/components/SettingsPane1.java b/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/gui/components/SettingsPane1.java index 6c6dcfce..90971ba4 100644 --- a/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/gui/components/SettingsPane1.java +++ b/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/gui/components/SettingsPane1.java @@ -72,7 +72,8 @@ public class SettingsPane1 extends VBox implements ChildController { /** * コンストラクタ
* - * @throws IOException FXMLファイルの読み込みに失敗した場合 + * @throws IOException + * FXMLファイルの読み込みに失敗した場合 */ public SettingsPane1() throws IOException { FXMLLoader loader = new FXMLLoader(getClass().getResource("SettingsPane1.fxml"), rb); @@ -105,7 +106,7 @@ public void init(MainController parent, Object... param) { // 4.値変更時のイベントハンドラの設定 BiConsumer> addListener = (target, key) -> target - .setOnAction(event -> ar.changeSetting(key, target.isSelected())); + .setOnAction(_ -> ar.changeSetting(key, target.isSelected())); addListener.accept(considerRowGapsCheckBox, SettingKeys.CONSIDER_ROW_GAPS); addListener.accept(considerColumnGapsCheckBox, SettingKeys.CONSIDER_COLUMN_GAPS); @@ -113,12 +114,12 @@ public void init(MainController parent, Object... param) { addListener.accept(showResultTextCheckBox, SettingKeys.SHOW_RESULT_REPORT); addListener.accept(exitWhenFinishedCheckBox, SettingKeys.EXIT_WHEN_FINISHED); - compareValuesOrFormulas.selectedToggleProperty().addListener((target, oldValue, newValue) -> ar + compareValuesOrFormulas.selectedToggleProperty().addListener((_, _, _) -> ar .changeSetting(SettingKeys.COMPARE_ON_FORMULA_STRING, compareFormulasRadioButton.isSelected())); - prioritizeSpeedOrAccuracy.selectedToggleProperty().addListener((target, oldValue, newValue) -> ar + prioritizeSpeedOrAccuracy.selectedToggleProperty().addListener((_, _, _) -> ar .changeSetting(SettingKeys.PRIORITIZE_SPEED, prioritizeSpeedRadioButton.isSelected())); - enableFuzzyMatchingCheckBox.setOnAction(event -> { + enableFuzzyMatchingCheckBox.setOnAction(_ -> { ar.changeSetting(SettingKeys.ENABLE_FUZZY_MATCHING, enableFuzzyMatchingCheckBox.isSelected()); parent.updateActiveComparison(); }); diff --git a/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/gui/components/SettingsPane2.java b/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/gui/components/SettingsPane2.java index 32ec0209..6120e37d 100644 --- a/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/gui/components/SettingsPane2.java +++ b/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/gui/components/SettingsPane2.java @@ -5,35 +5,29 @@ import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; -import java.util.Locale; import java.util.Objects; import java.util.Optional; import java.util.ResourceBundle; import java.util.stream.Stream; -import javafx.collections.FXCollections; import javafx.event.ActionEvent; import javafx.event.EventHandler; import javafx.fxml.FXML; import javafx.fxml.FXMLLoader; -import javafx.geometry.Pos; import javafx.scene.control.Alert; import javafx.scene.control.Alert.AlertType; import javafx.scene.control.Button; import javafx.scene.control.ButtonType; -import javafx.scene.control.ComboBox; -import javafx.scene.control.ListCell; -import javafx.scene.control.ListView; -import javafx.scene.image.Image; -import javafx.scene.image.ImageView; +import javafx.scene.control.Dialog; import javafx.scene.layout.VBox; import javafx.stage.DirectoryChooser; -import javafx.util.Callback; import xyz.hotchpotch.hogandiff.AppMain; import xyz.hotchpotch.hogandiff.AppResource; import xyz.hotchpotch.hogandiff.SettingKeys; +import xyz.hotchpotch.hogandiff.VersionMaster; import xyz.hotchpotch.hogandiff.gui.ChildController; import xyz.hotchpotch.hogandiff.gui.MainController; +import xyz.hotchpotch.hogandiff.gui.dialogs.SettingDetailsDialogPane; import xyz.hotchpotch.hogandiff.util.function.UnsafeConsumer; /** @@ -45,41 +39,6 @@ public class SettingsPane2 extends VBox implements ChildController { // [static members] ******************************************************** - private static enum LocaleItem { - - // [static members] ---------------------------------------------------- - - /** 日本語 */ - JA("日本語", Locale.JAPANESE, "jp.png"), - - /** 英語 */ - EN("English", Locale.ENGLISH, "us.png"), - - /** 中国語(簡体字) */ - ZH("簡体中文", Locale.SIMPLIFIED_CHINESE, "cn.png"); - - public static LocaleItem of(Locale locale) { - Objects.requireNonNull(locale); - - return Stream.of(values()) - .filter(item -> item.locale == locale) - .findFirst() - .orElseThrow(); - } - - // [instance members] -------------------------------------------------- - - private final String text; - private final Locale locale; - private final Image image; - - LocaleItem(String text, Locale locale, String imageSrc) { - this.text = text; - this.locale = locale; - this.image = new Image(imageSrc); - } - } - // [instance members] ****************************************************** private final AppResource ar = AppMain.appResource; @@ -88,9 +47,6 @@ public static LocaleItem of(Locale locale) { @FXML private GooglePane googlePane; - @FXML - private ComboBox localeComboBox; - @FXML private Button openWorkDirButton; @@ -100,10 +56,14 @@ public static LocaleItem of(Locale locale) { @FXML private Button deleteWorkDirButton; + @FXML + private Button detailsButton; + /** * コンストラクタ
* - * @throws IOException FXMLファイルの読み込みに失敗した場合 + * @throws IOException + * FXMLファイルの読み込みに失敗した場合 */ public SettingsPane2() throws IOException { FXMLLoader loader = new FXMLLoader(getClass().getResource("SettingsPane2.fxml"), rb); @@ -121,36 +81,38 @@ public void init(MainController parent, Object... param) { // 2.項目ごとの各種設定 googlePane.init(parent); - localeComboBox.setItems(FXCollections.observableArrayList(LocaleItem.values())); - localeComboBox.setButtonCell(cellFactory(false).call(null)); - localeComboBox.setCellFactory(cellFactory(true)); openWorkDirButton.setOnAction(openDir); changeWorkDirButton.setOnAction(changeDir); deleteWorkDirButton.setOnAction(deleteDir); - localeComboBox.setOnAction(event -> { - if (ar.changeSetting(SettingKeys.APP_LOCALE, localeComboBox.getValue().locale)) { - new Alert( - AlertType.INFORMATION, - "%s%n%n%s%n%n%s".formatted( - rb.getString("gui.component.SettingsPane2.051"), - rb.getString("gui.component.SettingsPane2.052"), - rb.getString("gui.component.SettingsPane2.053")), - ButtonType.OK) - .showAndWait(); + detailsButton.setOnAction(_ -> { + try { + SettingDetailsDialogPane detailsContent = new SettingDetailsDialogPane(); + detailsContent.init(); + Dialog detailsDialog = new Dialog<>(); + detailsDialog.setTitle(rb.getString("gui.component.SettingsPane2.060")); + detailsDialog.getDialogPane().setContent(detailsContent); + detailsDialog.getDialogPane().getButtonTypes().add(ButtonType.CLOSE); + detailsDialog.showAndWait(); + + } catch (IOException e) { + e.printStackTrace(); + // nop } }); // 3.初期値の設定 - Locale locale = ar.settings().get(SettingKeys.APP_LOCALE); - localeComboBox.setValue(LocaleItem.of(locale)); + // nop // 4.値変更時のイベントハンドラの設定 // nop + + // 5.その他 + VersionMaster.for_v0_27_0 = detailsButton; } - private final EventHandler openDir = event -> { + private final EventHandler openDir = _ -> { Path workDirBase = ar.settings().get(SettingKeys.WORK_DIR_BASE); try { @@ -171,7 +133,7 @@ public void init(MainController parent, Object... param) { } }; - private final EventHandler changeDir = event -> { + private final EventHandler changeDir = _ -> { Path workDirBase = ar.settings().get(SettingKeys.WORK_DIR_BASE); File newDir = null; @@ -215,7 +177,7 @@ public void init(MainController parent, Object... param) { } }; - private final EventHandler deleteDir = event -> { + private final EventHandler deleteDir = _ -> { Path workDirBase = ar.settings().get(SettingKeys.WORK_DIR_BASE); Optional result = new Alert( @@ -248,29 +210,4 @@ public void init(MainController parent, Object... param) { }); } }; - - private Callback, ListCell> cellFactory(boolean showText) { - return listView -> new ListCell<>() { - @Override - public void updateItem(LocaleItem item, boolean empty) { - super.updateItem(item, empty); - - if (empty || item == null) { - setText(null); - setGraphic(null); - } else { - ImageView iv = new ImageView(item.image); - iv.setFitHeight(17); - iv.setPreserveRatio(true); - setGraphic(iv); - - if (showText) { - setText(item.text); - } else { - this.setAlignment(Pos.CENTER); - } - } - } - }; - } } \ No newline at end of file diff --git a/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/gui/components/TargetSelectionPane.java b/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/gui/components/TargetSelectionPane.java index 10d76b91..184bae7f 100644 --- a/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/gui/components/TargetSelectionPane.java +++ b/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/gui/components/TargetSelectionPane.java @@ -42,10 +42,10 @@ import xyz.hotchpotch.hogandiff.gui.dialogs.PasswordDialog; import xyz.hotchpotch.hogandiff.logic.BookInfo; import xyz.hotchpotch.hogandiff.logic.BookInfo.Status; +import xyz.hotchpotch.hogandiff.logic.BookInfoLoader; import xyz.hotchpotch.hogandiff.logic.DirInfo; -import xyz.hotchpotch.hogandiff.logic.DirLoader; +import xyz.hotchpotch.hogandiff.logic.DirInfoLoader; import xyz.hotchpotch.hogandiff.logic.Factory; -import xyz.hotchpotch.hogandiff.logic.SheetNamesLoader; import xyz.hotchpotch.hogandiff.logic.google.GoogleFileInfo; import xyz.hotchpotch.hogandiff.logic.google.GoogleHandlingException; import xyz.hotchpotch.hogandiff.util.Pair.Side; @@ -111,7 +111,8 @@ private static boolean isDirOperation(AppMenu menu) { /** * コンストラクタ
* - * @throws IOException FXMLファイルの読み込みに失敗した場合 + * @throws IOException + * FXMLファイルの読み込みに失敗した場合 */ public TargetSelectionPane() throws IOException { FXMLLoader loader = new FXMLLoader(getClass().getResource("TargetSelectionPane.fxml"), rb); @@ -179,7 +180,7 @@ public void init(MainController parent, Object... params) { parent.bookInfoPropPair.get(side))); bookPathButton.setOnAction(this::chooseBook); - googleDriveButton.setOnAction(event -> { + googleDriveButton.setOnAction(_ -> { GooglePicker picker = new GooglePicker(); try { picker.downloadAndGetFileInfo() @@ -219,7 +220,7 @@ public void init(MainController parent, Object... params) { // 4.値変更時のイベントハンドラの設定 // ※このコントローラだけ特殊なので3と4を入れ替える - parent.menuProp.addListener((target, oldValue, newValue) -> { + parent.menuProp.addListener((_, oldValue, newValue) -> { DirInfo dirInfo = parent.dirInfoPropPair.get(side).getValue(); if (dirInfo != null && (newValue == AppMenu.COMPARE_DIRS || newValue == AppMenu.COMPARE_TREES) @@ -227,7 +228,7 @@ public void init(MainController parent, Object... params) { setDirPath(dirInfo.dirPath(), newValue == AppMenu.COMPARE_TREES); } }); - parent.bookInfoPropPair.get(side).addListener((target, oldValue, newValue) -> { + parent.bookInfoPropPair.get(side).addListener((_, _, newValue) -> { sheetNameChoiceBox.setItems(FXCollections.emptyObservableList()); if (newValue != null && !newValue.sheetNames().isEmpty()) { sheetNameChoiceBox.setItems(FXCollections.observableList(newValue.sheetNames())); @@ -393,7 +394,7 @@ private void setDirPath(Path newDirPath, boolean recursively) { } try { - DirLoader dirLoader = Factory.dirLoader( + DirInfoLoader dirLoader = Factory.dirInfoLoader( ar.settings().getAltered(SettingKeys.COMPARE_DIRS_RECURSIVELY, recursively)); DirInfo newDirInfo = dirLoader.loadDirInfo(newDirPath); parent.dirInfoPropPair.get(side).setValue(newDirInfo); @@ -464,7 +465,7 @@ private BookInfo readBookInfo(Path newBookPath, GoogleFileInfo googleFileInfo) { try { String readPassword = readPasswords.get(newBookPath); - SheetNamesLoader loader = Factory.sheetNamesLoader(newBookPath); + BookInfoLoader loader = Factory.bookInfoLoader(newBookPath); while (true) { BookInfo bookInfo = loader.loadBookInfo(newBookPath, readPassword) diff --git a/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/gui/components/TogglePane.java b/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/gui/components/TogglePane.java index 8696a640..3ce12349 100644 --- a/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/gui/components/TogglePane.java +++ b/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/gui/components/TogglePane.java @@ -36,7 +36,8 @@ public class TogglePane extends AnchorPane implements ChildController { /** * コンストラクタ
* - * @throws IOException FXMLファイルの読み込みに失敗した場合 + * @throws IOException + * FXMLファイルの読み込みに失敗した場合 */ public TogglePane() throws IOException { FXMLLoader loader = new FXMLLoader(getClass().getResource("TogglePane.fxml"), rb); @@ -61,7 +62,7 @@ public void init(MainController parent, Object... param) { toggleButton.setSelected(ar.settings().get(SettingKeys.SHOW_SETTINGS)); // 4.値変更時のイベントハンドラの設定 - toggleButton.setOnAction(event -> ar + toggleButton.setOnAction(_ -> ar .changeSetting(SettingKeys.SHOW_SETTINGS, toggleButton.isSelected())); } diff --git a/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/gui/dialogs/EditComparisonDialog.java b/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/gui/dialogs/EditComparisonDialog.java index ba89252e..6b21fc84 100644 --- a/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/gui/dialogs/EditComparisonDialog.java +++ b/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/gui/dialogs/EditComparisonDialog.java @@ -15,7 +15,8 @@ /** * 比較対象の組み合わせを編集するためのダイアログボックスです。
* - * @param 比較情報の型 + * @param + * 比較情報の型 * @author nmby */ public class EditComparisonDialog extends Dialog { @@ -29,9 +30,12 @@ public class EditComparisonDialog extends Dialog { /** * 新しいダイアログを構成します。
* - * @param comparison 比較情報 - * @throws IOException ダイアログの構成に失敗した場合 - * @throws NullPointerException パラメータが {@code null} の場合 + * @param comparison + * 比較情報 + * @throws IOException + * ダイアログの構成に失敗した場合 + * @throws NullPointerException + * パラメータが {@code null} の場合 */ public EditComparisonDialog(T comparison) throws IOException { Objects.requireNonNull(comparison); @@ -53,7 +57,7 @@ public EditComparisonDialog(T comparison) throws IOException { editComparisonDialogPane.getStylesheets().add( getClass().getResource("editComparisonDialog.css").toExternalForm()); - widthProperty().addListener((target, oldValue, newValue) -> { + widthProperty().addListener((_, _, newValue) -> { editComparisonDialogPane.setMaxWidth(newValue.doubleValue() - 20); editComparisonDialogPane.setMinWidth(newValue.doubleValue() - 20); }); diff --git a/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/gui/dialogs/EditComparisonDialogPane.java b/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/gui/dialogs/EditComparisonDialogPane.java index 2d2966be..aff58221 100644 --- a/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/gui/dialogs/EditComparisonDialogPane.java +++ b/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/gui/dialogs/EditComparisonDialogPane.java @@ -20,7 +20,7 @@ import xyz.hotchpotch.hogandiff.util.Pair; import xyz.hotchpotch.hogandiff.util.Pair.Side; -/*package*/ abstract class EditComparisonDialogPane extends VBox { +/* package */ abstract class EditComparisonDialogPane extends VBox { // [static members] ******************************************************** @@ -87,7 +87,8 @@ public ImageView createImageView(double size) { /** * コンストラクタ
* - * @throws IOException FXMLファイルの読み込みに失敗した場合 + * @throws IOException + * FXMLファイルの読み込みに失敗した場合 */ public EditComparisonDialogPane() throws IOException { FXMLLoader loader = new FXMLLoader(getClass().getResource("EditComparisonDialogPane.fxml"), rb); @@ -99,14 +100,17 @@ public EditComparisonDialogPane() throws IOException { /** * このダイアログボックス要素を初期化します。
* - * @param parentType 比較対象親要素の型 - * @param parentPair 比較対象親要素 - * @param childPairs 比較対象子要素 + * @param parentType + * 比較対象親要素の型 + * @param parentPair + * 比較対象親要素 + * @param childPairs + * 比較対象子要素 */ /* package */ void init(Pair parentPair) throws IOException { // コンテンツの長さが異なると均等にサイジングされないため、わざわざBindingとして実装することにする - childGridPane.widthProperty().addListener((target, oldValue, newValue) -> { + childGridPane.widthProperty().addListener((_, _, newValue) -> { double colWidth = (newValue.doubleValue() - 50) / 2; parentGridPane.getColumnConstraints().get(0).setPrefWidth(colWidth); parentGridPane.getColumnConstraints().get(2).setPrefWidth(colWidth); diff --git a/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/gui/dialogs/EditDirComparisonDialogPane.java b/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/gui/dialogs/EditDirComparisonDialogPane.java index 495ebb0a..96ce3bd7 100644 --- a/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/gui/dialogs/EditDirComparisonDialogPane.java +++ b/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/gui/dialogs/EditDirComparisonDialogPane.java @@ -18,7 +18,7 @@ import xyz.hotchpotch.hogandiff.logic.Factory; import xyz.hotchpotch.hogandiff.logic.PairingInfoBooks; import xyz.hotchpotch.hogandiff.logic.PairingInfoDirs; -import xyz.hotchpotch.hogandiff.logic.SheetNamesLoader; +import xyz.hotchpotch.hogandiff.logic.BookInfoLoader; import xyz.hotchpotch.hogandiff.util.Pair; import xyz.hotchpotch.hogandiff.util.Pair.Side; @@ -263,7 +263,7 @@ protected void onPasswordChallenge(int idx, Side side) { try { String readPassword = readPasswords.get(bookPath); - SheetNamesLoader loader = Factory.sheetNamesLoader(bookPath); + BookInfoLoader loader = Factory.bookInfoLoader(bookPath); BookInfo newBookInfo = null; while (true) { diff --git a/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/gui/dialogs/GoogleDownloadNoticeDialogPane.java b/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/gui/dialogs/GoogleDownloadNoticeDialogPane.java index 5291fd36..97401e93 100644 --- a/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/gui/dialogs/GoogleDownloadNoticeDialogPane.java +++ b/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/gui/dialogs/GoogleDownloadNoticeDialogPane.java @@ -18,7 +18,7 @@ /** * Googleドライブからのダウンロードに関する注意事項を表示するダイアログボックス要素です。
* - * @author hotchpotch + * @author nmby */ public class GoogleDownloadNoticeDialogPane extends VBox { @@ -41,7 +41,8 @@ public class GoogleDownloadNoticeDialogPane extends VBox { /** * コンストラクタ
* - * @throws IOException FXMLファイルの読み込みに失敗した場合 + * @throws IOException + * FXMLファイルの読み込みに失敗した場合 */ public GoogleDownloadNoticeDialogPane() throws IOException { FXMLLoader loader = new FXMLLoader(getClass().getResource("GoogleDownloadNoticeDialogPane.fxml"), rb); @@ -59,7 +60,7 @@ public void init() { // 2.イベントハンドラの設定 Path localDir = ar.settings().get(SettingKeys.WORK_DIR_BASE).resolve("googleDrive"); - localDirHyperlink.setOnAction(e -> { + localDirHyperlink.setOnAction(_ -> { try { Desktop.getDesktop().open(localDir.toFile()); } catch (IOException e1) { @@ -68,7 +69,7 @@ public void init() { } }); - dontShowNoMoreCheckBox.setOnAction(event -> ar.changeSetting( + dontShowNoMoreCheckBox.setOnAction(_ -> ar.changeSetting( SettingKeys.SHOW_GOOGLE_DL_NOTICE, !dontShowNoMoreCheckBox.isSelected())); diff --git a/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/gui/dialogs/GooglePicker.java b/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/gui/dialogs/GooglePicker.java index 18544895..aa244b6d 100644 --- a/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/gui/dialogs/GooglePicker.java +++ b/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/gui/dialogs/GooglePicker.java @@ -181,7 +181,8 @@ function pickerCallback(data) { * Google Pickerを開き、選択されたファイルの情報を取得します。
* * @return 選択されたファイルの情報。キャンセルされた場合は {@code null} - * @throws GoogleHandlingException ファイル情報の取得に失敗した場合 + * @throws GoogleHandlingException + * ファイル情報の取得に失敗した場合 */ public CompletableFuture downloadAndGetFileInfo() throws GoogleHandlingException { try { @@ -247,7 +248,9 @@ public CompletableFuture downloadAndGetFileInfo() throws GoogleH /** * Google Pickerを開いてファイル選択結果を取得 - * @param credential Google認証情報 + * + * @param credential + * Google認証情報 * @return 選択されたファイルの情報 */ private CompletableFuture openPicker() { @@ -267,7 +270,7 @@ private CompletableFuture openPicker() { throw new RuntimeException(e); } }) - .thenCompose(v -> fileSelectionFuture + .thenCompose(_ -> fileSelectionFuture .orTimeout(PICKER_TIMEOUT_SECONDS, TimeUnit.SECONDS) .handle((result, throwable) -> { if (throwable instanceof TimeoutException) { @@ -278,7 +281,7 @@ private CompletableFuture openPicker() { } return result; })) - .whenComplete((result, error) -> { + .whenComplete((_, _) -> { stopServer(); fileSelectionFuture = null; diff --git a/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/gui/dialogs/GoogleRevisionSelectorDialog.java b/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/gui/dialogs/GoogleRevisionSelectorDialog.java index ca409500..0c1a59fc 100644 --- a/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/gui/dialogs/GoogleRevisionSelectorDialog.java +++ b/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/gui/dialogs/GoogleRevisionSelectorDialog.java @@ -4,6 +4,8 @@ import java.util.List; import java.util.ResourceBundle; +import javafx.scene.control.Alert; +import javafx.scene.control.Alert.AlertType; import javafx.scene.control.ButtonType; import javafx.scene.control.Dialog; import javafx.scene.control.DialogPane; @@ -65,6 +67,14 @@ public GoogleRevisionSelectorDialog( ar.settings().get(SettingKeys.WORK_DIR_BASE).resolve("googleDrive")); } catch (GoogleHandlingException e) { + new Alert( + AlertType.ERROR, + "%s%n%s".formatted( + rb.getString("fx.GoogleRevisionSelectorDialog.010"), + e.getMessage()), + ButtonType.OK) + .showAndWait(); + e.printStackTrace(); return null; } diff --git a/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/gui/dialogs/GridRow.java b/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/gui/dialogs/GridRow.java index 7d3f3d4d..518ed523 100644 --- a/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/gui/dialogs/GridRow.java +++ b/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/gui/dialogs/GridRow.java @@ -43,11 +43,16 @@ public class GridRow extends Pane { /** * コンストラクタ * - * @param pane 親Pane - * @param idx GridPaneにおける行インデックス - * @param srcPair この {@link GridRow} が描画を担当するオブジェクト - * @throws NullPointerException パラメータが {@code null} の場合 - * @throws IllegalArgumentException {@code srcPair} が空の場合 + * @param pane + * 親Pane + * @param idx + * GridPaneにおける行インデックス + * @param srcPair + * この {@link GridRow} が描画を担当するオブジェクト + * @throws NullPointerException + * パラメータが {@code null} の場合 + * @throws IllegalArgumentException + * {@code srcPair} が空の場合 */ public GridRow( EditComparisonDialogPane pane, @@ -302,7 +307,7 @@ private LoadCompletedItem(Side side) { getStyleClass().add("loadCompletedItem"); if (srcPair.isPaired()) { - setOnMouseClicked(event -> pane.onClickPaired(idx)); + setOnMouseClicked(_ -> pane.onClickPaired(idx)); } } } @@ -337,7 +342,7 @@ private NeedsPasswordItem(Side side) { super(side); getStyleClass().add("needsPasswordItem"); - setOnMouseClicked(event -> pane.onPasswordChallenge(idx, side)); + setOnMouseClicked(_ -> pane.onPasswordChallenge(idx, side)); statusImageView.setImage(needsPasswordImage); } } @@ -371,7 +376,7 @@ protected UnpairButton() { setGraphic(linkOffImageView); setPrefWidth(50.0d); getStyleClass().add("unpairButton"); - setOnAction(event -> pane.unpair(idx)); + setOnAction(_ -> pane.unpair(idx)); } } } diff --git a/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/gui/dialogs/SettingDetailsDialogPane.java b/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/gui/dialogs/SettingDetailsDialogPane.java new file mode 100644 index 00000000..4d98cc88 --- /dev/null +++ b/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/gui/dialogs/SettingDetailsDialogPane.java @@ -0,0 +1,207 @@ +package xyz.hotchpotch.hogandiff.gui.dialogs; + +import java.awt.Desktop; +import java.io.IOException; +import java.nio.file.Files; +import java.util.Locale; +import java.util.Objects; +import java.util.Optional; +import java.util.ResourceBundle; +import java.util.stream.Stream; + +import javafx.application.Platform; +import javafx.collections.FXCollections; +import javafx.fxml.FXML; +import javafx.fxml.FXMLLoader; +import javafx.geometry.Pos; +import javafx.scene.control.Alert; +import javafx.scene.control.Alert.AlertType; +import javafx.scene.control.Button; +import javafx.scene.control.ButtonType; +import javafx.scene.control.CheckBox; +import javafx.scene.control.ComboBox; +import javafx.scene.control.ListCell; +import javafx.scene.control.ListView; +import javafx.scene.image.Image; +import javafx.scene.image.ImageView; +import javafx.scene.layout.VBox; +import javafx.util.Callback; +import xyz.hotchpotch.hogandiff.AppMain; +import xyz.hotchpotch.hogandiff.AppResource; +import xyz.hotchpotch.hogandiff.SettingKeys; +import xyz.hotchpotch.hogandiff.gui.UpdateChecker; +import xyz.hotchpotch.hogandiff.logic.google.GoogleCredential; + +/** + * 詳細設定ダイアログの内容部分を提供します。
+ * + * @author nmby + */ +public class SettingDetailsDialogPane extends VBox { + + // [static members] ******************************************************** + + private static final AppResource ar = AppMain.appResource; + private static final ResourceBundle rb = ar.get(); + + private static enum LocaleItem { + + // [static members] ---------------------------------------------------- + + /** 日本語 */ + JA("日本語", Locale.JAPANESE, "jp.png"), + + /** 英語 */ + EN("English", Locale.ENGLISH, "us.png"), + + /** 中国語(簡体字) */ + ZH("簡体中文", Locale.SIMPLIFIED_CHINESE, "cn.png"); + + public static LocaleItem of(Locale locale) { + Objects.requireNonNull(locale); + + return Stream.of(values()) + .filter(item -> item.locale == locale) + .findFirst() + .orElseThrow(); + } + + // [instance members] -------------------------------------------------- + + private final String text; + private final Locale locale; + private final Image image; + + LocaleItem(String text, Locale locale, String imageSrc) { + this.text = text; + this.locale = locale; + this.image = new Image(imageSrc); + } + } + + // [instance members] ****************************************************** + + @FXML + private ComboBox localeComboBox; + + @FXML + private CheckBox checkUpdatesCheckBox; + + @FXML + private Button checkUpdatesImmediatelyButton; + + @FXML + private Button openSettingsFileButton; + + @FXML + private Button resetSettingsButton; + + /** + * コンストラクタ
+ * + * @throws IOException + * FXMLファイルの読み込みに失敗した場合 + */ + public SettingDetailsDialogPane() throws IOException { + FXMLLoader loader = new FXMLLoader(getClass().getResource("SettingDetailsDialogPane.fxml"), rb); + loader.setRoot(this); + loader.setController(this); + loader.load(); + } + + /** + * このオブジェクトを初期化します。
+ */ + public void init() { + // 1.disableプロパティのバインディング + // nop + + // 2.項目ごとの各種設定 + localeComboBox.setItems(FXCollections.observableArrayList(LocaleItem.values())); + localeComboBox.setButtonCell(cellFactory(false).call(null)); + localeComboBox.setCellFactory(cellFactory(true)); + + localeComboBox.setOnAction(_ -> { + if (ar.changeSetting(SettingKeys.APP_LOCALE, localeComboBox.getValue().locale)) { + new Alert( + AlertType.INFORMATION, + "%s%n%n%s%n%n%s".formatted( + rb.getString("gui.component.SettingsPane2.051"), + rb.getString("gui.component.SettingsPane2.052"), + rb.getString("gui.component.SettingsPane2.053")), + ButtonType.OK) + .showAndWait(); + } + }); + + checkUpdatesImmediatelyButton.setOnAction(_ -> { + UpdateChecker.execute(true); + }); + + openSettingsFileButton.setOnAction(_ -> { + try { + Desktop.getDesktop().open(AppResource.APP_PROP_PATH.toFile()); + } catch (IOException e) { + e.printStackTrace(); + // nop + } + }); + + resetSettingsButton.setOnAction(_ -> { + Optional result = new Alert( + AlertType.CONFIRMATION, + rb.getString("gui.dialogs.SettingDetailsDialogPane.010")) + .showAndWait(); + + if (result.isPresent() && result.get() == ButtonType.OK) { + try { + Files.deleteIfExists(AppResource.APP_PROP_PATH); + GoogleCredential credential = GoogleCredential.get(false); + if (credential != null) { + credential.deleteCredential(); + } + Platform.exit(); + } catch (Exception e) { + e.printStackTrace(); + // nop + } + } + }); + + // 3.初期値の設定 + Locale locale = ar.settings().get(SettingKeys.APP_LOCALE); + localeComboBox.setValue(LocaleItem.of(locale)); + + checkUpdatesCheckBox.setSelected(ar.settings().get(SettingKeys.CHECK_UPDATES)); + + // 4.値変更時のイベントハンドラの設定 + checkUpdatesCheckBox.setOnAction(_ -> ar.changeSetting( + SettingKeys.CHECK_UPDATES, + checkUpdatesCheckBox.isSelected())); + } + + private Callback, ListCell> cellFactory(boolean showText) { + return _ -> new ListCell<>() { + @Override + public void updateItem(LocaleItem item, boolean empty) { + super.updateItem(item, empty); + + if (empty || item == null) { + setText(null); + setGraphic(null); + } else { + ImageView iv = new ImageView(item.image); + iv.setFitHeight(17); + iv.setPreserveRatio(true); + setGraphic(iv); + + if (showText) { + setText(item.text); + } else { + this.setAlignment(Pos.CENTER); + } + } + } + }; + } +} diff --git a/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/logic/SheetNamesLoader.java b/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/logic/BookInfoLoader.java similarity index 68% rename from xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/logic/SheetNamesLoader.java rename to xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/logic/BookInfoLoader.java index 2797c618..dbe382e9 100644 --- a/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/logic/SheetNamesLoader.java +++ b/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/logic/BookInfoLoader.java @@ -6,10 +6,10 @@ import java.util.Objects; import java.util.Set; -import xyz.hotchpotch.hogandiff.logic.plain.SheetNamesLoaderCombined; -import xyz.hotchpotch.hogandiff.logic.poi.SheetNamesLoaderWithPoiEventApi; -import xyz.hotchpotch.hogandiff.logic.poi.SheetNamesLoaderWithPoiUserApi; -import xyz.hotchpotch.hogandiff.logic.sax.SheetNamesLoaderWithSax; +import xyz.hotchpotch.hogandiff.logic.plain.BookInfoLoaderCombined; +import xyz.hotchpotch.hogandiff.logic.poi.BookInfoLoaderWithPoiEventApi; +import xyz.hotchpotch.hogandiff.logic.poi.BookInfoLoaderWithPoiUserApi; +import xyz.hotchpotch.hogandiff.logic.sax.BookInfoLoaderWithSax; /** * Excelブック情報を抽出するローダーを表します。
@@ -18,7 +18,7 @@ * @author nmby */ @FunctionalInterface -public interface SheetNamesLoader { +public interface BookInfoLoader { // [static members] ******************************************************** @@ -30,19 +30,19 @@ public interface SheetNamesLoader { * @throws NullPointerException {@code bookPath} が {@code null} の場合 * @throws UnsupportedOperationException {@code bookPath} がサポート対象外の形式の場合 */ - public static SheetNamesLoader of(Path bookPath) { + public static BookInfoLoader of(Path bookPath) { Objects.requireNonNull(bookPath); Set targetSheetTypes = EnumSet.of(SheetType.WORKSHEET); return switch (BookType.of(bookPath)) { - case XLS -> SheetNamesLoaderCombined.of(List.of( - () -> SheetNamesLoaderWithPoiEventApi.of(targetSheetTypes), - () -> SheetNamesLoaderWithPoiUserApi.of(targetSheetTypes))); + case XLS -> BookInfoLoaderCombined.of(List.of( + () -> BookInfoLoaderWithPoiEventApi.of(targetSheetTypes), + () -> BookInfoLoaderWithPoiUserApi.of(targetSheetTypes))); - case XLSX, XLSM -> SheetNamesLoaderCombined.of(List.of( - () -> SheetNamesLoaderWithSax.of(targetSheetTypes), - () -> SheetNamesLoaderWithPoiUserApi.of(targetSheetTypes))); + case XLSX, XLSM -> BookInfoLoaderCombined.of(List.of( + () -> BookInfoLoaderWithSax.of(targetSheetTypes), + () -> BookInfoLoaderWithPoiUserApi.of(targetSheetTypes))); // FIXME: [No.02 .xlsbのサポート] case XLSB -> throw new UnsupportedOperationException("unsupported book type: " + BookType.XLSB); diff --git a/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/logic/DirLoader.java b/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/logic/DirInfoLoader.java similarity index 80% rename from xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/logic/DirLoader.java rename to xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/logic/DirInfoLoader.java index b1140d12..715a03d2 100644 --- a/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/logic/DirLoader.java +++ b/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/logic/DirInfoLoader.java @@ -2,7 +2,7 @@ import java.nio.file.Path; -import xyz.hotchpotch.hogandiff.logic.plain.DirLoaderStandard; +import xyz.hotchpotch.hogandiff.logic.plain.DirInfoLoaderStandard; /** * フォルダ情報を抽出するローダーを表します。
@@ -11,7 +11,7 @@ * @author nmby */ @FunctionalInterface -public interface DirLoader { +public interface DirInfoLoader { // [static members] ******************************************************** @@ -21,8 +21,8 @@ public interface DirLoader { * @param recursively 子フォルダも再帰的に抽出するか * @return フォルダ情報を抽出するローダー */ - public static DirLoader of(boolean recursively) { - return new DirLoaderStandard(recursively); + public static DirInfoLoader of(boolean recursively) { + return new DirInfoLoaderStandard(recursively); } // [instance members] ****************************************************** diff --git a/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/logic/Factory.java b/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/logic/Factory.java index c31bb68b..7784808d 100644 --- a/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/logic/Factory.java +++ b/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/logic/Factory.java @@ -19,9 +19,9 @@ * @author nmby */ public class Factory { - + // [static members] ******************************************************** - + /** * Excelブック情報を抽出するローダーを返します。
* @@ -30,12 +30,12 @@ public class Factory { * @throws NullPointerException {@code bookPath} が {@code null} の場合 * @throws UnsupportedOperationException {@code bookPath} がサポート対象外の形式の場合 */ - public static SheetNamesLoader sheetNamesLoader(Path bookPath) { + public static BookInfoLoader bookInfoLoader(Path bookPath) { Objects.requireNonNull(bookPath); - - return SheetNamesLoader.of(bookPath); + + return BookInfoLoader.of(bookPath); } - + /** * Excelシートからセルデータを抽出するローダーを返します。
* @@ -49,16 +49,16 @@ public static SheetNamesLoader sheetNamesLoader(Path bookPath) { public static CellsLoader cellsLoader(Settings settings, BookInfo bookInfo) { Objects.requireNonNull(settings); Objects.requireNonNull(bookInfo); - + // 設計メモ: // Settings を扱うのは Factory の層までとし、これ以下の各機能へは // Settings 丸ごとではなく、必要な個別のパラメータを渡すこととする。 - + boolean useCachedValue = !settings.get(SettingKeys.COMPARE_ON_FORMULA_STRING); - + return CellsLoader.of(bookInfo, useCachedValue); } - + /** * フォルダ情報を抽出するローダーを返します。
* @@ -66,13 +66,13 @@ public static CellsLoader cellsLoader(Settings settings, BookInfo bookInfo) { * @return フォルダ情報を抽出するローダー * @throws NullPointerException パラメータが {@code null} の場合 */ - public static DirLoader dirLoader(Settings settings) { + public static DirInfoLoader dirInfoLoader(Settings settings) { Objects.requireNonNull(settings); - + boolean recursively = settings.get(SettingKeys.COMPARE_DIRS_RECURSIVELY); - return DirLoader.of(recursively); + return DirInfoLoader.of(recursively); } - + /** * 2つのExcelブックに含まれるシート名同士の対応関係を決めるマッチャーを返します。
* @@ -82,7 +82,7 @@ public static DirLoader dirLoader(Settings settings) { */ public static Matcher sheetNamesMatcher(Settings settings) { Objects.requireNonNull(settings); - + boolean enableFuzzyMatching = settings.get(SettingKeys.ENABLE_FUZZY_MATCHING); return enableFuzzyMatching ? Matcher.combinedMatcherOf(List.of( @@ -92,7 +92,7 @@ public static Matcher sheetNamesMatcher(Settings settings) { (s1, s2) -> StringDiffUtil.levenshteinDistance(s1, s2) + 1))) : Matcher.identityMatcherOf(); } - + /** * 2つのフォルダに含まれるExcelブック情報同士の対応関係を決めるマッチャーを返します。
* Excelブックパスの末尾のファイル名に基づいて対応関係を求めます。
@@ -103,7 +103,7 @@ public static Matcher sheetNamesMatcher(Settings settings) { */ public static Matcher bookInfosMatcher(Settings settings) { Objects.requireNonNull(settings); - + boolean enableFuzzyMatching = settings.get(SettingKeys.ENABLE_FUZZY_MATCHING); return enableFuzzyMatching ? Matcher.combinedMatcherOf(List.of( @@ -117,7 +117,7 @@ public static Matcher bookInfosMatcher(Settings settings) { }))) : Matcher.identityMatcherOf(BookInfo::bookName); } - + /** * 2つのフォルダツリーに含まれるフォルダ同士の対応関係を決めるマッチャーを返します。
* @@ -127,7 +127,7 @@ public static Matcher bookInfosMatcher(Settings settings) { */ public static Matcher dirInfosMatcher(Settings settings) { Objects.requireNonNull(settings); - + boolean enableFuzzyMatching = settings.get(SettingKeys.ENABLE_FUZZY_MATCHING); return enableFuzzyMatching ? Matcher.combinedMatcherOf(List.of( @@ -135,26 +135,26 @@ public static Matcher dirInfosMatcher(Settings settings) { fuzzyButSimpleDirInfosMatcher)) : strictDirInfosMatcher; } - + private static final Function dirNameExtractor = d -> d.dirPath().getFileName().toString(); - + private static final Matcher strictDirInfosMatcher = Matcher.identityMatcherOf(dirNameExtractor); - + private static final Matcher fuzzyButSimpleDirInfosMatcher = Matcher.minimumCostFlowMatcherOf( d -> d.childDirInfos().size() + d.childBookInfos().size(), (d1, d2) -> { List childrenNames1 = d1.childDirInfos().stream().map(dirNameExtractor).toList(); List childrenNames2 = d2.childDirInfos().stream().map(dirNameExtractor).toList(); - + int gapChildren = (int) Matcher.identityMatcherOf().makeIdxPairs(childrenNames1, childrenNames2) .stream().filter(Predicate.not(IntPair::isPaired)).count(); int gapBookNames = (int) Matcher.identityMatcherOf() .makeIdxPairs(d1.childBookInfos(), d2.childBookInfos()) .stream().filter(Predicate.not(IntPair::isPaired)).count(); - + return gapChildren + gapBookNames; }); - + /** * 2つのExcelシートから抽出したセルセット同士を比較するコンパレータを返します。
* @@ -164,14 +164,14 @@ public static Matcher dirInfosMatcher(Settings settings) { */ public static ComparatorOfSheets sheetComparator(Settings settings) { Objects.requireNonNull(settings); - + boolean considerRowGaps = settings.get(SettingKeys.CONSIDER_ROW_GAPS); boolean considerColumnGaps = settings.get(SettingKeys.CONSIDER_COLUMN_GAPS); boolean prioritizeSpeed = settings.get(SettingKeys.PRIORITIZE_SPEED); - + return ComparatorOfSheets.of(considerRowGaps, considerColumnGaps, prioritizeSpeed); } - + /** * Excelブックの差分個所に色を付けて新しいファイルとして保存する * ペインターを返します。
@@ -188,11 +188,11 @@ public static Painter painter( Settings settings, Path bookPath, String readPassword) { - + Objects.requireNonNull(settings); Objects.requireNonNull(bookPath); // readPassword may be null. - + short redundantColor = settings.get(SettingKeys.REDUNDANT_COLOR); short diffColor = settings.get(SettingKeys.DIFF_COLOR); Color redundantCommentColor = settings.get(SettingKeys.REDUNDANT_COMMENT_COLOR); @@ -202,7 +202,7 @@ public static Painter painter( Color redundantSheetColor = settings.get(SettingKeys.REDUNDANT_SHEET_COLOR); Color diffSheetColor = settings.get(SettingKeys.DIFF_SHEET_COLOR); Color sameSheetColor = settings.get(SettingKeys.SAME_SHEET_COLOR); - + return Painter.of( bookPath, readPassword, @@ -216,9 +216,9 @@ public static Painter painter( diffSheetColor, sameSheetColor); } - + // [instance members] ****************************************************** - + private Factory() { } } diff --git a/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/logic/google/GoogleFileFetcher.java b/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/logic/google/GoogleFileFetcher.java index 9b706cdd..b8268bda 100644 --- a/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/logic/google/GoogleFileFetcher.java +++ b/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/logic/google/GoogleFileFetcher.java @@ -177,7 +177,7 @@ private void downloadFromUrl(String urlString, Path outputPath) throws IOExcepti outputStream.flush(); } } else { - throw new IOException("fail to export.。HTTP status code: " + responseCode); + throw new IOException("fail to export. HTTP status code: " + responseCode); } } finally { diff --git a/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/logic/plain/SheetNamesLoaderCombined.java b/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/logic/plain/BookInfoLoaderCombined.java similarity index 82% rename from xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/logic/plain/SheetNamesLoaderCombined.java rename to xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/logic/plain/BookInfoLoaderCombined.java index 1571fbc7..d9ea50ac 100644 --- a/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/logic/plain/SheetNamesLoaderCombined.java +++ b/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/logic/plain/BookInfoLoaderCombined.java @@ -9,15 +9,15 @@ import xyz.hotchpotch.hogandiff.logic.BookHandler; import xyz.hotchpotch.hogandiff.logic.BookInfo; import xyz.hotchpotch.hogandiff.logic.BookType; -import xyz.hotchpotch.hogandiff.logic.SheetNamesLoader; +import xyz.hotchpotch.hogandiff.logic.BookInfoLoader; /** - * 処理が成功するまで複数のローダーで順に処理を行う {@link SheetNamesLoader} の実装です。
+ * 処理が成功するまで複数のローダーで順に処理を行う {@link BookInfoLoader} の実装です。
* * @author nmby */ @BookHandler -public class SheetNamesLoaderCombined implements SheetNamesLoader { +public class BookInfoLoaderCombined implements BookInfoLoader { // [static members] ******************************************************** @@ -29,20 +29,20 @@ public class SheetNamesLoaderCombined implements SheetNamesLoader { * @throws NullPointerException パラメータが {@code null} の場合 * @throws IllegalArgumentException {@code suppliers} が空の場合 */ - public static SheetNamesLoader of(List> suppliers) { + public static BookInfoLoader of(List> suppliers) { Objects.requireNonNull(suppliers); if (suppliers.isEmpty()) { throw new IllegalArgumentException("param \"suppliers\" is empty."); } - return new SheetNamesLoaderCombined(suppliers); + return new BookInfoLoaderCombined(suppliers); } // [instance members] ****************************************************** - private final List> suppliers; + private final List> suppliers; - private SheetNamesLoaderCombined(List> suppliers) { + private BookInfoLoaderCombined(List> suppliers) { assert suppliers != null; this.suppliers = List.copyOf(suppliers); @@ -76,10 +76,10 @@ public BookInfo loadBookInfo( CommonUtil.ifNotSupportedBookTypeThenThrow(getClass(), BookType.of(bookPath)); try { - Iterator> itr = suppliers.iterator(); + Iterator> itr = suppliers.iterator(); while (itr.hasNext()) { - SheetNamesLoader loader = itr.next().get(); + BookInfoLoader loader = itr.next().get(); BookInfo bookInfo = loader.loadBookInfo(bookPath, readPassword); switch (bookInfo.status()) { diff --git a/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/logic/plain/DirLoaderStandard.java b/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/logic/plain/DirInfoLoaderStandard.java similarity index 85% rename from xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/logic/plain/DirLoaderStandard.java rename to xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/logic/plain/DirInfoLoaderStandard.java index da70412e..cfd53fd0 100644 --- a/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/logic/plain/DirLoaderStandard.java +++ b/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/logic/plain/DirInfoLoaderStandard.java @@ -12,19 +12,19 @@ import xyz.hotchpotch.hogandiff.logic.BookInfo; import xyz.hotchpotch.hogandiff.logic.BookType; import xyz.hotchpotch.hogandiff.logic.DirInfo; -import xyz.hotchpotch.hogandiff.logic.DirLoader; +import xyz.hotchpotch.hogandiff.logic.DirInfoLoader; import xyz.hotchpotch.hogandiff.logic.ExcelHandlingException; import xyz.hotchpotch.hogandiff.logic.Factory; -import xyz.hotchpotch.hogandiff.logic.SheetNamesLoader; +import xyz.hotchpotch.hogandiff.logic.BookInfoLoader; import xyz.hotchpotch.hogandiff.util.function.UnsafeFunction; import xyz.hotchpotch.hogandiff.util.function.UnsafeFunction.ResultOrThrown; /** - * {@link DirLoader} の標準的な実装です。
+ * {@link DirInfoLoader} の標準的な実装です。
* * @author nmby */ -public class DirLoaderStandard implements DirLoader { +public class DirInfoLoaderStandard implements DirInfoLoader { // [static members] ******************************************************** @@ -47,7 +47,7 @@ private static boolean isHandleableExcelBook(Path path) { * * @param recursively 子フォルダの情報も再帰的にロードするか */ - public DirLoaderStandard(boolean recursively) { + public DirInfoLoaderStandard(boolean recursively) { this.recursively = recursively; } @@ -78,10 +78,10 @@ private DirInfo loadDir2(Path path) throws ExcelHandlingException { List childBookPaths = Files.list(path) .filter(f -> Files.isRegularFile(f, LinkOption.NOFOLLOW_LINKS)) - .filter(DirLoaderStandard::isHandleableExcelBook) + .filter(DirInfoLoaderStandard::isHandleableExcelBook) .sorted() .map(bookPath -> { - SheetNamesLoader bookLoader = Factory.sheetNamesLoader(bookPath); + BookInfoLoader bookLoader = Factory.bookInfoLoader(bookPath); return bookLoader.loadBookInfo(bookPath, null); }) .toList(); diff --git a/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/logic/poi/SheetNamesLoaderWithPoiEventApi.java b/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/logic/poi/BookInfoLoaderWithPoiEventApi.java similarity index 92% rename from xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/logic/poi/SheetNamesLoaderWithPoiEventApi.java rename to xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/logic/poi/BookInfoLoaderWithPoiEventApi.java index f55b2631..211b3ea6 100644 --- a/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/logic/poi/SheetNamesLoaderWithPoiEventApi.java +++ b/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/logic/poi/BookInfoLoaderWithPoiEventApi.java @@ -22,19 +22,19 @@ import xyz.hotchpotch.hogandiff.logic.BookHandler; import xyz.hotchpotch.hogandiff.logic.BookInfo; import xyz.hotchpotch.hogandiff.logic.BookType; -import xyz.hotchpotch.hogandiff.logic.SheetNamesLoader; +import xyz.hotchpotch.hogandiff.logic.BookInfoLoader; import xyz.hotchpotch.hogandiff.logic.SheetType; import xyz.hotchpotch.hogandiff.logic.plain.CommonUtil; /** * Apache POI イベントモデル API を利用して * .xls 形式のExcelブックから - * シート名の一覧を抽出する {@link SheetNamesLoader} の実装です。
+ * シート名の一覧を抽出する {@link BookInfoLoader} の実装です。
* * @author nmby */ @BookHandler(targetTypes = { BookType.XLS }) -public class SheetNamesLoaderWithPoiEventApi implements SheetNamesLoader { +public class BookInfoLoaderWithPoiEventApi implements BookInfoLoader { // [static members] ******************************************************** @@ -136,20 +136,20 @@ private List getSheetNames(Set targetTypes) { * @throws NullPointerException パラメータが {@code null} の場合 * @throws IllegalArgumentException {@code targetTypes} が空の場合 */ - public static SheetNamesLoader of(Set targetTypes) { + public static BookInfoLoader of(Set targetTypes) { Objects.requireNonNull(targetTypes); if (targetTypes.isEmpty()) { throw new IllegalArgumentException("targetTypes is empty."); } - return new SheetNamesLoaderWithPoiEventApi(targetTypes); + return new BookInfoLoaderWithPoiEventApi(targetTypes); } // [instance members] ****************************************************** private final Set targetTypes; - private SheetNamesLoaderWithPoiEventApi(Set targetTypes) { + private BookInfoLoaderWithPoiEventApi(Set targetTypes) { assert targetTypes != null; this.targetTypes = EnumSet.copyOf(targetTypes); diff --git a/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/logic/poi/SheetNamesLoaderWithPoiUserApi.java b/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/logic/poi/BookInfoLoaderWithPoiUserApi.java similarity index 89% rename from xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/logic/poi/SheetNamesLoaderWithPoiUserApi.java rename to xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/logic/poi/BookInfoLoaderWithPoiUserApi.java index 37cc7d05..1f1d4bc4 100644 --- a/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/logic/poi/SheetNamesLoaderWithPoiUserApi.java +++ b/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/logic/poi/BookInfoLoaderWithPoiUserApi.java @@ -16,19 +16,19 @@ import xyz.hotchpotch.hogandiff.logic.BookHandler; import xyz.hotchpotch.hogandiff.logic.BookInfo; import xyz.hotchpotch.hogandiff.logic.BookType; -import xyz.hotchpotch.hogandiff.logic.SheetNamesLoader; +import xyz.hotchpotch.hogandiff.logic.BookInfoLoader; import xyz.hotchpotch.hogandiff.logic.SheetType; import xyz.hotchpotch.hogandiff.logic.plain.CommonUtil; /** * Apache POI のユーザーモデル API を利用して * .xlsx/.xlsm/.xls 形式のExcelブックから - * シート名の一覧を抽出する {@link SheetNamesLoader} の実装です。
+ * シート名の一覧を抽出する {@link BookInfoLoader} の実装です。
* * @author nmby */ @BookHandler(targetTypes = { BookType.XLSX, BookType.XLSM, BookType.XLS }) -public class SheetNamesLoaderWithPoiUserApi implements SheetNamesLoader { +public class BookInfoLoaderWithPoiUserApi implements BookInfoLoader { // [static members] ******************************************************** @@ -40,20 +40,20 @@ public class SheetNamesLoaderWithPoiUserApi implements SheetNamesLoader { * @throws NullPointerException パラメータが {@code null} の場合 * @throws IllegalArgumentException {@code targetTypes} が空の場合 */ - public static SheetNamesLoader of(Set targetTypes) { + public static BookInfoLoader of(Set targetTypes) { Objects.requireNonNull(targetTypes); if (targetTypes.isEmpty()) { throw new IllegalArgumentException("targetTypes is empty."); } - return new SheetNamesLoaderWithPoiUserApi(targetTypes); + return new BookInfoLoaderWithPoiUserApi(targetTypes); } // [instance members] ****************************************************** private final Set targetTypes; - private SheetNamesLoaderWithPoiUserApi(Set targetTypes) { + private BookInfoLoaderWithPoiUserApi(Set targetTypes) { assert targetTypes != null; this.targetTypes = EnumSet.copyOf(targetTypes); diff --git a/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/logic/poi/CellsLoaderWithPoiEventApi.java b/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/logic/poi/CellsLoaderWithPoiEventApi.java index d19132f2..919dcba2 100644 --- a/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/logic/poi/CellsLoaderWithPoiEventApi.java +++ b/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/logic/poi/CellsLoaderWithPoiEventApi.java @@ -119,13 +119,14 @@ private Listener1(String sheetName, boolean extractCachedValue) { /** * .xls 形式のExcelブックからセルデータを抽出します。
* - * @param record レコード + * @param record + * レコード * @throws NoSuchElementException - * 指定された名前のシートが見つからない場合 + * 指定された名前のシートが見つからない場合 * @throws UnsupportedOperationException - * 指定された名前のシートがワークシートではなかった場合 + * 指定された名前のシートがワークシートではなかった場合 * @throws UnsupportedOperationException - * 数式セルからキャッシュされた計算値ではなく数式文字列を抽出しようとした場合 + * 数式セルからキャッシュされた計算値ではなく数式文字列を抽出しようとした場合 */ @Override public void processRecord(Record record) { @@ -162,8 +163,10 @@ public void processRecord(Record record) { /** * BOUNDSHEET レコードの中から、目的のシートが何番目に定義されているかを探します。
* - * @param record レコード - * @throws NoSuchElementException 指定された名前のシートが見つからない場合 + * @param record + * レコード + * @throws NoSuchElementException + * 指定された名前のシートが見つからない場合 */ private void searchingSheetDefinition(Record record) { if (record instanceof BoundSheetRecord bsRec) { @@ -182,7 +185,8 @@ private void searchingSheetDefinition(Record record) { /** * Excelブック共通の SST レコードを読み取ります。
* - * @param record レコード + * @param record + * レコード */ private void readingSstData(Record record) { if (record instanceof SSTRecord sstRec) { @@ -200,9 +204,10 @@ private void readingSstData(Record record) { /** * 目的のシートが定義される BOF レコードを探します。
* - * @param record レコード + * @param record + * レコード * @throws UnsupportedOperationException - * 指定された名前のシートがグラフシートもしくはマクロシートだった場合 + * 指定された名前のシートがグラフシートもしくはマクロシートだった場合 */ private void searchingSheetBody(Record record) { if (record instanceof BOFRecord bofRec) { @@ -240,9 +245,10 @@ private void searchingSheetBody(Record record) { /** * 目的のシートがワークシートなのかダイアログシートなのかを確認します。
* - * @param record レコード + * @param record + * レコード * @throws UnsupportedOperationException - * 指定された名前のシートがダイアログシートだった場合 + * 指定された名前のシートがダイアログシートだった場合 */ private void checkWorksheetOrDialogsheet(Record record) { if (record instanceof WSBoolRecord wsbRec) { @@ -260,7 +266,8 @@ private void checkWorksheetOrDialogsheet(Record record) { /** * 目的のシートのセル内容物とセルコメントを読み取ります。
* - * @param record レコード + * @param record + * レコード */ private void readingCellContentsAndComments(Record record) { assert record != null; @@ -351,7 +358,7 @@ assert record != null; } break; - case EOFRecord eofRec: // 次ステップに移行 + case EOFRecord _: // 次ステップに移行 step = ProcessingStep.COMPLETED; break; @@ -376,10 +383,11 @@ assert record != null; /** * FORMULA レコードからセル格納値を抽出します。
* - * @param fRec レコード + * @param fRec + * レコード * @return セル格納値 * @throws UnsupportedOperationException - * キャッシュされた計算値ではなく数式文字列を抽出しようとした場合 + * キャッシュされた計算値ではなく数式文字列を抽出しようとした場合 */ private String getValueFromFormulaRecord(FormulaRecord fRec) { if (extractCachedValue) { @@ -427,8 +435,8 @@ private String getValueFromFormulaRecord(FormulaRecord fRec) { * コンストラクタ * * @param extractCachedValue - * 数式セルからキャッシュされた計算値を抽出する場合は {@code true}、 - * 数式文字列を抽出する場合は {@code false} + * 数式セルからキャッシュされた計算値を抽出する場合は {@code true}、 + * 数式文字列を抽出する場合は {@code false} */ public CellsLoaderWithPoiEventApi(boolean extractCachedValue) { this.extractCachedValue = extractCachedValue; @@ -438,12 +446,12 @@ public CellsLoaderWithPoiEventApi(boolean extractCachedValue) { * {@inheritDoc} * * @throws NullPointerException - * {@code bookInfo}, {@code sheetName} のいずれかが - * {@code null} の場合 + * {@code bookInfo}, {@code sheetName} のいずれかが + * {@code null} の場合 * @throws IllegalArgumentException - * {@code bookInfo} がサポート対象外の形式の場合 + * {@code bookInfo} がサポート対象外の形式の場合 * @throws ExcelHandlingException - * 処理に失敗した場合 + * 処理に失敗した場合 */ // 例外カスケードのポリシーについて: // ・プログラミングミスに起因するこのメソッドの呼出不正は RuntimeException の派生でレポートする。 diff --git a/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/logic/poi/PoiUtil.java b/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/logic/poi/PoiUtil.java index ad9133fc..c430c53e 100644 --- a/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/logic/poi/PoiUtil.java +++ b/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/logic/poi/PoiUtil.java @@ -93,11 +93,14 @@ public class PoiUtil { * 以上の理由により、このメソッドは「{@code 10:27}」と入力されたセルの値を * {@code "1899/12/31 10:27:00.000"} という文字列で返します。
* - * @param cell 対象のセル - * @param useCachedValue 対象のセルの形式が数式の場合に、 - * 数式ではなくキャッシュされた算出値を返す場合は {@code true} + * @param cell + * 対象のセル + * @param useCachedValue + * 対象のセルの形式が数式の場合に、 + * 数式ではなくキャッシュされた算出値を返す場合は {@code true} * @return セルの格納値を表す文字列 - * @throws NullPointerException パラメータが {@code null} の場合 + * @throws NullPointerException + * パラメータが {@code null} の場合 */ public static String getCellContentAsString(Cell cell, boolean useCachedValue) { Objects.requireNonNull(cell); @@ -139,9 +142,11 @@ public static String getCellContentAsString(Cell cell, boolean useCachedValue) { /** * Excelシートの種類を推定して、可能性のある種類を返します。
* - * @param sheet Excelシート + * @param sheet + * Excelシート * @return 可能性のある種類 - * @throws NullPointerException パラメータが {@code null} の場合 + * @throws NullPointerException + * パラメータが {@code null} の場合 */ // このロジックで合ってるのかはさっぱり分からん // FIXME: [No.01 シート識別不正 - usermodel] 識別精度を上げたい... @@ -149,9 +154,9 @@ public static Set possibleTypes(Sheet sheet) { Objects.requireNonNull(sheet); return switch (sheet) { - case XSSFChartSheet xcs -> EnumSet.of(SheetType.CHART_SHEET); - case XSSFDialogsheet xds -> EnumSet.of(SheetType.DIALOG_SHEET); - case XSSFSheet xs -> EnumSet.of(SheetType.WORKSHEET, SheetType.MACRO_SHEET); + case XSSFChartSheet _ -> EnumSet.of(SheetType.CHART_SHEET); + case XSSFDialogsheet _ -> EnumSet.of(SheetType.DIALOG_SHEET); + case XSSFSheet _ -> EnumSet.of(SheetType.WORKSHEET, SheetType.MACRO_SHEET); case HSSFSheet hSheet -> { try { @@ -178,8 +183,10 @@ public static Set possibleTypes(Sheet sheet) { * 指定されたExcelブックに設定されているあらゆる色をクリアし、 * セルコメントを非表示にします。
* - * @param book Excelブック - * @throws NullPointerException パラメータが {@code null} の場合 + * @param book + * Excelブック + * @throws NullPointerException + * パラメータが {@code null} の場合 */ public static void clearAllColors(Workbook book) { Objects.requireNonNull(book); @@ -314,10 +321,14 @@ private static void clearAllColors(HSSFWorkbook book) { /** * 指定されたExcelシート上の指定された行に指定された色を付けます。
* - * @param sheet Excelシート - * @param rowIdxs 色を付ける行のインデックス値 - * @param color 着色する色のインデックス値 - * @throws NullPointerException パラメータが {@code null} の場合 + * @param sheet + * Excelシート + * @param rowIdxs + * 色を付ける行のインデックス値 + * @param color + * 着色する色のインデックス値 + * @throws NullPointerException + * パラメータが {@code null} の場合 */ public static void paintRows(Sheet sheet, List rowIdxs, short color) { Objects.requireNonNull(sheet); @@ -369,10 +380,14 @@ public static void paintRows(Sheet sheet, List rowIdxs, short color) { /** * 指定されたExcelシートの指定された列に指定された色を付けます。
* - * @param sheet Excelシート - * @param columnIdxs 色を付ける行のインデックス値 - * @param color 着色する色のインデックス値 - * @throws NullPointerException パラメータが {@code null} の場合 + * @param sheet + * Excelシート + * @param columnIdxs + * 色を付ける行のインデックス値 + * @param color + * 着色する色のインデックス値 + * @throws NullPointerException + * パラメータが {@code null} の場合 */ public static void paintColumns(Sheet sheet, List columnIdxs, short color) { Objects.requireNonNull(sheet); @@ -417,10 +432,14 @@ public static void paintColumns(Sheet sheet, List columnIdxs, short col /** * 指定されたExcelシート上の指定された位置のセルに指定された色を付けます。
* - * @param sheet Excelシート - * @param addresses 色を付けるセルの位置 - * @param color 着色する色のインデックス値 - * @throws NullPointerException パラメータが {@code null} の場合 + * @param sheet + * Excelシート + * @param addresses + * 色を付けるセルの位置 + * @param color + * 着色する色のインデックス値 + * @throws NullPointerException + * パラメータが {@code null} の場合 */ public static void paintCells( Sheet sheet, @@ -466,7 +485,7 @@ public static void paintCells( CellPropertyType.FILL_PATTERN, FillPatternType.SOLID_FOREGROUND, CellPropertyType.FILL_FOREGROUND_COLOR, color); - currStyles.forEach((currStyle, cs) -> { + currStyles.forEach((_, cs) -> { Iterator itr = cs.iterator(); if (itr.hasNext()) { Cell first = itr.next(); @@ -481,10 +500,14 @@ public static void paintCells( * 指定されたExcelシート上の指定された位置のセルに付されているコメントに * 指定された色を付け、表示状態にします。
* - * @param sheet Excelシート - * @param addresses 色を付けるセルコメントの位置 - * @param color 着色する色 - * @throws NullPointerException パラメータが {@code null} の場合 + * @param sheet + * Excelシート + * @param addresses + * 色を付けるセルコメントの位置 + * @param color + * 着色する色 + * @throws NullPointerException + * パラメータが {@code null} の場合 */ public static void paintComments( Sheet sheet, @@ -521,9 +544,12 @@ public static void paintComments( /** * 指定されたExcelシートの見出しに指定された色を付けます。
* - * @param sheet Excelシート - * @param color 着色する色 - * @throws NullPointerException パラメータが {@code null} の場合 + * @param sheet + * Excelシート + * @param color + * 着色する色 + * @throws NullPointerException + * パラメータが {@code null} の場合 */ public static void paintSheetTab( Sheet sheet, @@ -539,7 +565,7 @@ public static void paintSheetTab( new DefaultIndexedColorMap())); break; - case HSSFSheet hSheet: + case HSSFSheet _: // FIXME: [No.03 着色関連] シート見出しの色の設定方法が分からない break; @@ -552,12 +578,17 @@ public static void paintSheetTab( * シート上の指定した位置の {@link Cell} オブジェクトを返します。
* 指定した位置のセルオブジェクトが存在しない場合は作成して返します。
* - * @param sheet シート - * @param r 行インデックス(0開始) - * @param c 列インデックス(0開始) + * @param sheet + * シート + * @param r + * 行インデックス(0開始) + * @param c + * 列インデックス(0開始) * @return セルオブジェクト - * @throws NullPointerException パラメータが {@code null} の場合 - * @throws IllegalArgumentException {@code r}, {@code c} のいずれかが負数の場合 + * @throws NullPointerException + * パラメータが {@code null} の場合 + * @throws IllegalArgumentException + * {@code r}, {@code c} のいずれかが負数の場合 */ public static Cell getCell( Sheet sheet, @@ -577,11 +608,15 @@ public static Cell getCell( * シート上の指定した位置の {@link Cell} オブジェクトを返します。
* 指定した位置のセルオブジェクトが存在しない場合は {@link Optional#empty} を返します。
* - * @param sheet シート - * @param r 行インデックス(0開始) - * @param c 列インデックス(0開始) + * @param sheet + * シート + * @param r + * 行インデックス(0開始) + * @param c + * 列インデックス(0開始) * @return セルオブジェクト(存在しない場合は {@link Optional#empty}) - * @throws NullPointerException パラメータが {@code null} の場合 + * @throws NullPointerException + * パラメータが {@code null} の場合 */ public static Optional getCellIfPresent( Sheet sheet, @@ -602,10 +637,14 @@ public static Optional getCellIfPresent( * シート上の指定した位置のセルに値を設定します。
* 指定した位置のセルオブジェクトが存在しない場合は作成して値を設定します。
* - * @param sheet シート - * @param r 行インデックス(0開始) - * @param c 列インデックス(0開始) - * @param value 設定する値 + * @param sheet + * シート + * @param r + * 行インデックス(0開始) + * @param c + * 列インデックス(0開始) + * @param value + * 設定する値 * @return セルオブジェクト */ // 醜いオーバーロードだ・・ @@ -619,10 +658,14 @@ public static Cell setCellValue(Sheet sheet, int r, int c, String value) { * シート上の指定した位置のセルに値を設定します。
* 指定した位置のセルオブジェクトが存在しない場合は作成して値を設定します。
* - * @param sheet シート - * @param r 行インデックス(0開始) - * @param c 列インデックス(0開始) - * @param value 設定する値 + * @param sheet + * シート + * @param r + * 行インデックス(0開始) + * @param c + * 列インデックス(0開始) + * @param value + * 設定する値 * @return セルオブジェクト */ // 醜いオーバーロードだ・・ @@ -636,10 +679,14 @@ public static Cell setCellValue(Sheet sheet, int r, int c, double value) { * シート上の指定した位置のセルに値を設定します。
* 指定した位置のセルオブジェクトが存在しない場合は作成して値を設定します。
* - * @param sheet シート - * @param r 行インデックス(0開始) - * @param c 列インデックス(0開始) - * @param value 設定する値 + * @param sheet + * シート + * @param r + * 行インデックス(0開始) + * @param c + * 列インデックス(0開始) + * @param value + * 設定する値 * @return セルオブジェクト */ // 醜いオーバーロードだ・・ @@ -656,11 +703,15 @@ public static Cell setCellValue(Sheet sheet, int r, int c, LocalDateTime value) * - セルの内容 * これ以外の内容はコピーしませんのでご注意ください。
* - * @param sheet シート - * @param srcRowNo コピー元行番号 - * @param dstRowNo コピー先行番号 + * @param sheet + * シート + * @param srcRowNo + * コピー元行番号 + * @param dstRowNo + * コピー先行番号 * @return コピー先の行 - * @throws NullPointerException パラメータが {@code null} の場合 + * @throws NullPointerException + * パラメータが {@code null} の場合 */ public static Row copyRow( Sheet sheet, @@ -710,10 +761,13 @@ private static void copyCellValue(Cell srcCell, Cell dstCell) { /** * 指定されたセルに指定されたパスへのハイパーリンクを設定します。
* - * @param cell ハイパーリンクを付与するセル - * @param path ハイパーリンク化するパス + * @param cell + * ハイパーリンクを付与するセル + * @param path + * ハイパーリンク化するパス * @return セル - * @throws NullPointerException パラメータが {@code null} の場合 + * @throws NullPointerException + * パラメータが {@code null} の場合 */ public static Cell setHyperlink( Cell cell, @@ -738,10 +792,13 @@ public static Cell setHyperlink( /** * 指定されたセルに指定されたURLへのハイパーリンクを設定します。
* - * @param cell ハイパーリンクを付与するセル - * @param url ハイパーリンク化するURL + * @param cell + * ハイパーリンクを付与するセル + * @param url + * ハイパーリンク化するURL * @return セル - * @throws NullPointerException パラメータが {@code null} の場合 + * @throws NullPointerException + * パラメータが {@code null} の場合 */ public static Cell setHyperlink( Cell cell, diff --git a/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/logic/sax/SheetNamesLoaderWithSax.java b/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/logic/sax/BookInfoLoaderWithSax.java similarity index 89% rename from xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/logic/sax/SheetNamesLoaderWithSax.java rename to xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/logic/sax/BookInfoLoaderWithSax.java index 255afaec..84b4113e 100644 --- a/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/logic/sax/SheetNamesLoaderWithSax.java +++ b/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/logic/sax/BookInfoLoaderWithSax.java @@ -10,7 +10,7 @@ import xyz.hotchpotch.hogandiff.logic.BookInfo; import xyz.hotchpotch.hogandiff.logic.BookType; import xyz.hotchpotch.hogandiff.logic.PasswordHandlingException; -import xyz.hotchpotch.hogandiff.logic.SheetNamesLoader; +import xyz.hotchpotch.hogandiff.logic.BookInfoLoader; import xyz.hotchpotch.hogandiff.logic.SheetType; import xyz.hotchpotch.hogandiff.logic.plain.CommonUtil; import xyz.hotchpotch.hogandiff.logic.sax.SaxUtil.SheetInfo; @@ -18,12 +18,12 @@ /** * SAX (Simple API for XML) を利用して * .xlsx/.xlsm 形式のExcelブックから - * シート名の一覧を抽出する {@link SheetNamesLoader} の実装です。
+ * シート名の一覧を抽出する {@link BookInfoLoader} の実装です。
* * @author nmby */ @BookHandler(targetTypes = { BookType.XLSX, BookType.XLSM }) -public class SheetNamesLoaderWithSax implements SheetNamesLoader { +public class BookInfoLoaderWithSax implements BookInfoLoader { // [static members] ******************************************************** @@ -35,20 +35,20 @@ public class SheetNamesLoaderWithSax implements SheetNamesLoader { * @throws NullPointerException パラメータが {@code null} の場合 * @throws IllegalArgumentException {@code targetTypes} が空の場合 */ - public static SheetNamesLoader of(Set targetTypes) { + public static BookInfoLoader of(Set targetTypes) { Objects.requireNonNull(targetTypes); if (targetTypes.isEmpty()) { throw new IllegalArgumentException("targetTypes is empty."); } - return new SheetNamesLoaderWithSax(targetTypes); + return new BookInfoLoaderWithSax(targetTypes); } // [instance members] ****************************************************** private final Set targetTypes; - private SheetNamesLoaderWithSax(Set targetTypes) { + private BookInfoLoaderWithSax(Set targetTypes) { assert targetTypes != null; this.targetTypes = EnumSet.copyOf(targetTypes); diff --git a/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/logic/sax/CellsLoaderWithSax.java b/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/logic/sax/CellsLoaderWithSax.java index eddc053a..8380fac1 100644 --- a/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/logic/sax/CellsLoaderWithSax.java +++ b/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/logic/sax/CellsLoaderWithSax.java @@ -91,12 +91,14 @@ private static class Handler1 extends DefaultHandler { // [static members] ---------------------------------------------------- + private static final String xmlns = "http://schemas.openxmlformats.org/spreadsheetml/2006/main"; + // [instance members] -------------------------------------------------- private final boolean extractCachedValue; private final List sst; - private final Deque qNames = new ArrayDeque<>(); + private final Deque localNames = new ArrayDeque<>(); private final Map texts = new HashMap<>(); private final Map addressToContent = new HashMap<>(); @@ -117,9 +119,9 @@ private Handler1( public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { - qNames.addFirst(qName); + localNames.addFirst(localName); - if ("c".equals(qName)) { + if (xmlns.equals(uri) && "c".equals(localName)) { type = XSSFCellType.of(attributes.getValue("t")); address = attributes.getValue("r"); texts.clear(); @@ -128,14 +130,14 @@ public void startElement(String uri, String localName, String qName, Attributes @Override public void characters(char ch[], int start, int length) { - String qName = qNames.getFirst(); - texts.putIfAbsent(qName, new StringBuilder()); - texts.get(qName).append(ch, start, length); + String localName = localNames.getFirst(); + texts.putIfAbsent(localName, new StringBuilder()); + texts.get(localName).append(ch, start, length); } @Override public void endElement(String uri, String localName, String qName) { - if ("c".equals(qName)) { + if (xmlns.equals(uri) && "c".equals(localName)) { StringBuilder vText = texts.get("v"); StringBuilder fText = texts.get("f"); StringBuilder tText = texts.get("t"); @@ -181,7 +183,7 @@ public void endElement(String uri, String localName, String qName) { addressToContent.put(address, value); } - qNames.removeFirst(); + localNames.removeFirst(); type = null; address = null; texts.clear(); @@ -193,6 +195,8 @@ private static class Handler2 extends DefaultHandler { // [static members] ---------------------------------------------------- + private static final String xmlns = "http://schemas.openxmlformats.org/spreadsheetml/2006/main"; + // [instance members] -------------------------------------------------- private final Map addressToComment = new HashMap<>(); @@ -204,7 +208,7 @@ private static class Handler2 extends DefaultHandler { public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { - if ("comment".equals(qName)) { + if (xmlns.equals(uri) && "comment".equals(localName)) { address = attributes.getValue("ref"); comment = new StringBuilder(); } @@ -219,7 +223,7 @@ public void characters(char ch[], int start, int length) { @Override public void endElement(String uri, String localName, String qName) { - if ("comment".equals(qName)) { + if (xmlns.equals(uri) && "comment".equals(localName)) { addressToComment.put(address, comment.toString()); address = null; comment = null; @@ -296,6 +300,7 @@ public Set loadCells( UnsafeFunction, Exception> processor = zis -> { SAXParserFactory factory = SAXParserFactory.newInstance(); + factory.setNamespaceAware(true); SAXParser parser = factory.newSAXParser(); Handler1 handler1 = new Handler1(extractCachedValue, sst); Handler2 handler2 = new Handler2(); diff --git a/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/logic/sax/SaxUtil.java b/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/logic/sax/SaxUtil.java index 7b77ba3d..63a1fd57 100644 --- a/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/logic/sax/SaxUtil.java +++ b/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/logic/sax/SaxUtil.java @@ -84,6 +84,9 @@ private static class Handler1 extends DefaultHandler { // [static members] ---------------------------------------------------- + private static final String xmlns = "http://schemas.openxmlformats.org/spreadsheetml/2006/main"; + private static final String xmlns_r = "http://schemas.openxmlformats.org/officeDocument/2006/relationships"; + private static record SheetNameAndId(String sheetName, String id) { }; @@ -97,10 +100,10 @@ private static boolean isTarget(String entryName) { @Override public void startElement(String uri, String localName, String qName, Attributes attributes) { - if ("sheet".equals(qName)) { + if (xmlns.equals(uri) && "sheet".equals(localName)) { sheetNameAndId.add(new SheetNameAndId( attributes.getValue("name"), - attributes.getValue("r:id"))); + attributes.getValue(xmlns_r, "id"))); } } } @@ -122,6 +125,8 @@ private static class Handler2 extends DefaultHandler { // [static members] ---------------------------------------------------- + private static final String xmlns = "http://schemas.openxmlformats.org/package/2006/relationships"; + private static boolean isTarget(String entryName) { return "xl/_rels/workbook.xml.rels".equals(entryName); } @@ -133,7 +138,7 @@ private static boolean isTarget(String entryName) { @Override public void startElement(String uri, String localName, String qName, Attributes attributes) { - if ("Relationship".equals(qName)) { + if (xmlns.equals(uri) && "Relationship".equals(localName)) { String id = attributes.getValue("Id"); SheetType type = switch (attributes.getValue("Type")) { case "http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet" -> SheetType.WORKSHEET; @@ -169,6 +174,7 @@ private static class Handler3 extends DefaultHandler { // [static members] ---------------------------------------------------- + private static final String xmlns = "http://schemas.openxmlformats.org/package/2006/relationships"; private static final String commentRelType = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments"; private static final String vmlDrawingRelType = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/vmlDrawing"; @@ -188,7 +194,7 @@ private static String entryFor(String sheetSource) { @Override public void startElement(String uri, String localName, String qName, Attributes attributes) { - if ("Relationship".equals(qName)) { + if (xmlns.equals(uri) && "Relationship".equals(localName)) { switch (attributes.getValue("Type")) { case commentRelType: commentSource = attributes.getValue("Target").replace("../", "xl/"); @@ -217,28 +223,30 @@ private static class Handler4 extends DefaultHandler { // [static members] ---------------------------------------------------- + private static final String xmlns = "http://schemas.openxmlformats.org/spreadsheetml/2006/main"; + private static boolean isTarget(String entryName) { return "xl/sharedStrings.xml".equals(entryName); } // [instance members] -------------------------------------------------- - private final Deque qNames = new ArrayDeque<>(); + private final Deque localNames = new ArrayDeque<>(); private final List sst = new ArrayList<>(); private StringBuilder text; private boolean waitingText; @Override public void startElement(String uri, String localName, String qName, Attributes attributes) { - if ("si".equals(qName)) { + if (xmlns.equals(uri) && "si".equals(localName)) { text = new StringBuilder(); - } else if ("t".equals(qName)) { - String parent = qNames.getFirst(); + } else if (xmlns.equals(uri) && "t".equals(localName)) { + String parent = localNames.getFirst(); if ("si".equals(parent) || "r".equals(parent)) { waitingText = true; } } - qNames.addFirst(qName); + localNames.addFirst(localName); } @Override @@ -250,13 +258,13 @@ public void characters(char ch[], int start, int length) { @Override public void endElement(String uri, String localName, String qName) { - if ("si".equals(qName)) { + if (xmlns.equals(uri) && "si".equals(localName)) { sst.add(text.toString()); text = null; - } else if ("t".equals(qName)) { + } else if (xmlns.equals(uri) && "t".equals(localName)) { waitingText = false; } - qNames.removeFirst(); + localNames.removeFirst(); } } @@ -438,6 +446,7 @@ public static List loadSheetInfos( UnsafeFunction, Exception> processor = zis -> { SAXParserFactory factory = SAXParserFactory.newInstance(); + factory.setNamespaceAware(true); SAXParser parser = factory.newSAXParser(); Handler1 handler1 = new Handler1(); Handler2 handler2 = new Handler2(); @@ -465,10 +474,10 @@ public static List loadSheetInfos( } } - if (readPassword == null && handler1.sheetNameAndId.size() == 0) { - // 大変雑ではあるが、例外がスローされずしかしシート情報を読み取れなかった場合は - // 読取パスワードでロックされていると見做してしまう。 - throw new PasswordHandlingException(); + if (handler1.sheetNameAndId.isEmpty()) { + // 何らかの理由によりシート名を読み取れなかった場合。 + // パスワードでロックされている場合もあり得るが、例外を投げて後続のローダーに委ねることにする。 + throw new ExcelHandlingException("no sheets found in the book : %s".formatted(bookPath)); } return handler1.sheetNameAndId.stream() @@ -516,6 +525,7 @@ public static List loadSharedStrings( UnsafeFunction, Exception> processor = zis -> { SAXParserFactory factory = SAXParserFactory.newInstance(); + factory.setNamespaceAware(true); SAXParser parser = factory.newSAXParser(); Handler4 handler4 = new Handler4(); ZipEntry entry; diff --git a/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/logic/stax/PainterWithStax.java b/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/logic/stax/PainterWithStax.java index 406d440b..28b19ba0 100644 --- a/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/logic/stax/PainterWithStax.java +++ b/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/logic/stax/PainterWithStax.java @@ -76,6 +76,8 @@ public static class StylesManager { // [static members] ---------------------------------------------------- + private static final String xmlns = "http://schemas.openxmlformats.org/spreadsheetml/2006/main"; + /** * {@link StylesManager} オブジェクトを生成して返します。
* @@ -104,8 +106,8 @@ private StylesManager(Document styles) { assert styles != null; this.styles = styles; - elemCellXfs = (Element) styles.getElementsByTagName("cellXfs").item(0); - elemFills = (Element) styles.getElementsByTagName("fills").item(0); + elemCellXfs = (Element) styles.getElementsByTagNameNS(xmlns, "cellXfs").item(0); + elemFills = (Element) styles.getElementsByTagNameNS(xmlns, "fills").item(0); cellXfsCount = Integer.parseInt(elemCellXfs.getAttribute("count")); fillsCount = Integer.parseInt(elemFills.getAttribute("count")); } @@ -141,7 +143,7 @@ private int copyXf(int styleIdx, short colorIdx) { cellXfsCount++; elemCellXfs.setAttribute("count", Integer.toString(cellXfsCount)); - Element originalXf = (Element) elemCellXfs.getElementsByTagName("xf").item(styleIdx); + Element originalXf = (Element) elemCellXfs.getElementsByTagNameNS(xmlns, "xf").item(styleIdx); Element newXf = (Element) originalXf.cloneNode(true); elemCellXfs.appendChild(newXf); @@ -166,14 +168,14 @@ private int createFill(short colorIdx) { fillsCount++; elemFills.setAttribute("count", Integer.toString(fillsCount)); - Element newFill = styles.createElement("fill"); + Element newFill = styles.createElementNS(xmlns, "fill"); elemFills.appendChild(newFill); - Element patternFill = styles.createElement("patternFill"); + Element patternFill = styles.createElementNS(xmlns, "patternFill"); patternFill.setAttribute("patternType", "solid"); newFill.appendChild(patternFill); - Element fgColor = styles.createElement("fgColor"); + Element fgColor = styles.createElementNS(xmlns, "fgColor"); fgColor.setAttribute("indexed", Integer.toString(colorIdx)); patternFill.appendChild(fgColor); @@ -183,7 +185,11 @@ private int createFill(short colorIdx) { private static final XMLInputFactory inFactory = XMLInputFactory.newInstance(); private static final XMLOutputFactory outFactory = XMLOutputFactory.newInstance(); - private static final DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance(); + private static final DocumentBuilderFactory docBuilderFactory; + static { + docBuilderFactory = DocumentBuilderFactory.newInstance(); + docBuilderFactory.setNamespaceAware(true); + } private static final TransformerFactory transformerFactory = TransformerFactory.newInstance(); // [instance members] ****************************************************** diff --git a/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/logic/stax/readers/BufferingReader.java b/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/logic/stax/readers/BufferingReader.java index c48b79be..03984a4c 100644 --- a/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/logic/stax/readers/BufferingReader.java +++ b/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/logic/stax/readers/BufferingReader.java @@ -2,11 +2,16 @@ import java.util.ArrayDeque; import java.util.Deque; +import java.util.Iterator; import java.util.NoSuchElementException; +import javax.xml.namespace.NamespaceContext; import javax.xml.namespace.QName; +import javax.xml.stream.XMLEventFactory; import javax.xml.stream.XMLEventReader; import javax.xml.stream.XMLStreamException; +import javax.xml.stream.events.Attribute; +import javax.xml.stream.events.StartElement; import javax.xml.stream.events.XMLEvent; /** @@ -24,6 +29,9 @@ public abstract class BufferingReader implements XMLEventReader { // [instance members] ****************************************************** + /** イベントファクトリ */ + protected final XMLEventFactory eventFactory = XMLEventFactory.newFactory(); + /** ソースリーダー */ protected final XMLEventReader source; @@ -33,19 +41,41 @@ public abstract class BufferingReader implements XMLEventReader { /** 現在の要素ツリー */ protected final Deque currTree = new ArrayDeque<>(); + /** 名前空間コンテキスト */ + protected NamespaceContext namespaces; + private boolean isReady; /** * 新しいリーダーを生成します。
* * @param source ソースリーダー + * @throws XMLStreamException XMLイベントの解析に失敗した場合 */ - protected BufferingReader(XMLEventReader source) { + protected BufferingReader(XMLEventReader source) throws XMLStreamException { assert source != null; this.source = source; } + /** + * 指定された情報から開始要素イベントを生成します。
+ * + * @param qName 要素名 + * @param attrs 属性イテレータ + * @return 開始要素イベント + */ + protected StartElement createStartElement(QName qName, Iterator attrs) { + return namespaces != null + ? eventFactory.createStartElement( + namespaces.getPrefix(qName.getNamespaceURI()), + qName.getNamespaceURI(), + qName.getLocalPart(), + attrs, + null) + : eventFactory.createStartElement(qName, attrs, null); + } + /** * このリーダーの現在の状態で {@link #hasNext()}, {@link #peek()}, {@link #nextEvent()}, * {@link #next()} @@ -133,7 +163,9 @@ public XMLEvent nextEvent() throws XMLStreamException { : buffer.remove(); if (next.isStartElement()) { - currTree.addLast(next.asStartElement().getName()); + StartElement se = next.asStartElement(); + namespaces = se.getNamespaceContext(); + currTree.addLast(se.getName()); } else if (next.isEndElement()) { currTree.removeLast(); } diff --git a/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/logic/stax/readers/CloseAndUnpaintCommentsReader.java b/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/logic/stax/readers/CloseAndUnpaintCommentsReader.java index b014f557..db269803 100644 --- a/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/logic/stax/readers/CloseAndUnpaintCommentsReader.java +++ b/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/logic/stax/readers/CloseAndUnpaintCommentsReader.java @@ -5,7 +5,6 @@ import java.util.Objects; import javax.xml.namespace.QName; -import javax.xml.stream.XMLEventFactory; import javax.xml.stream.XMLEventReader; import javax.xml.stream.XMLStreamException; import javax.xml.stream.events.Attribute; @@ -29,16 +28,15 @@ public class CloseAndUnpaintCommentsReader extends BufferingReader { // [static members] ******************************************************** - private static final XMLEventFactory eventFactory = XMLEventFactory.newFactory(); - /** * 新しいリーダーを構成します。
* * @param source ソースリーダー * @return 新しいリーダー + * @throws XMLStreamException XMLイベントの解析に失敗した場合 * @throws NullPointerException パラメータが {@code null} の場合 */ - public static XMLEventReader of(XMLEventReader source) { + public static XMLEventReader of(XMLEventReader source) throws XMLStreamException { Objects.requireNonNull(source); return new CloseAndUnpaintCommentsReader(source); @@ -49,7 +47,7 @@ public static XMLEventReader of(XMLEventReader source) { private boolean inCommentShape; private boolean inNoteObject; - private CloseAndUnpaintCommentsReader(XMLEventReader source) { + private CloseAndUnpaintCommentsReader(XMLEventReader source) throws XMLStreamException { super(source); } @@ -119,6 +117,6 @@ private StartElement createNewShape(StartElement originalShape) { attrs.remove(NONS_QNAME.FILL_COLOR); attrs.remove(NONS_QNAME.STROKE_COLOR); - return eventFactory.createStartElement(V_QNAME.SHAPE, attrs.values().iterator(), null); + return createStartElement(V_QNAME.SHAPE, attrs.values().iterator()); } } diff --git a/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/logic/stax/readers/FilteringReader.java b/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/logic/stax/readers/FilteringReader.java index 2a723083..accf594e 100644 --- a/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/logic/stax/readers/FilteringReader.java +++ b/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/logic/stax/readers/FilteringReader.java @@ -46,9 +46,11 @@ private Builder(XMLEventReader source) { /** * このビルダーにフィルターを追加します。
* - * @param qNames 除外する要素を表すQNameの階層 + * @param qNames + * 除外する要素を表すQNameの階層 * @return このビルダー - * @throws NullPointerException {@code filter} が {@code null} の場合 + * @throws NullPointerException + * {@code filter} が {@code null} の場合 */ public Builder addFilter(QName... qNames) { if (qNames.length == 0) { @@ -80,23 +82,27 @@ public Builder addFilter(QName... qNames) { /** * このビルダーにフィルターを追加します。
* - * @param filter フィルダー + * @param filter + * フィルダー * @return このビルダー - * @throws NullPointerException パラメータが {@code null} の場合 + * @throws NullPointerException + * パラメータが {@code null} の場合 */ public Builder addFilter(Predicate filter) { Objects.requireNonNull(filter); - filters.add((currTree, start) -> filter.test(start)); + filters.add((_, start) -> filter.test(start)); return this; } /** * このビルダーにフィルターを追加します。
* - * @param filter フィルダー + * @param filter + * フィルダー * @return このビルダー - * @throws NullPointerException パラメータが {@code null} の場合 + * @throws NullPointerException + * パラメータが {@code null} の場合 */ public Builder addFilter(BiPredicate, ? super StartElement> filter) { Objects.requireNonNull(filter); @@ -108,8 +114,10 @@ public Builder addFilter(BiPredicate, ? super StartElement> * このビルダーからリーダーを構成します。
* * @return 新しいリーダー + * @throws XMLStreamException + * XMLイベントの解析に失敗した場合 */ - public XMLEventReader build() { + public XMLEventReader build() throws XMLStreamException { return new FilteringReader(this); } } @@ -117,9 +125,11 @@ public XMLEventReader build() { /** * このクラスのビルダーを返します。
* - * @param source ソースリーダー + * @param source + * ソースリーダー * @return このクラスのビルダー - * @throws NullPointerException パラメータが {@code null} の場合 + * @throws NullPointerException + * パラメータが {@code null} の場合 */ public static Builder builder(XMLEventReader source) { Objects.requireNonNull(source); @@ -131,7 +141,7 @@ public static Builder builder(XMLEventReader source) { private final List, ? super StartElement>> filters; - private FilteringReader(Builder builder) { + private FilteringReader(Builder builder) throws XMLStreamException { super(builder.source); filters = builder.filters; diff --git a/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/logic/stax/readers/PaintColumnsReader.java b/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/logic/stax/readers/PaintColumnsReader.java index 7beb5e1c..114aaf20 100644 --- a/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/logic/stax/readers/PaintColumnsReader.java +++ b/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/logic/stax/readers/PaintColumnsReader.java @@ -14,7 +14,6 @@ import java.util.Set; import javax.xml.namespace.QName; -import javax.xml.stream.XMLEventFactory; import javax.xml.stream.XMLEventReader; import javax.xml.stream.XMLStreamException; import javax.xml.stream.events.Attribute; @@ -40,8 +39,6 @@ public class PaintColumnsReader extends BufferingReader { // [static members] ******************************************************** - private static final XMLEventFactory eventFactory = XMLEventFactory.newFactory(); - /** * 新しいリーダーを構成します。
* @@ -50,6 +47,7 @@ public class PaintColumnsReader extends BufferingReader { * @param targetColumns 着色対象の列インデックス(0 開始) * @param colorIdx 着色する色のインデックス * @return 新しいリーダー + * @throws XMLStreamException XMLイベントの解析に失敗した場合 * @throws NullPointerException パラメータが {@code null} の場合 * @throws IllegalArgumentException {@code targetColumns} の長さが 0 の場合 */ @@ -57,7 +55,8 @@ public static XMLEventReader of( XMLEventReader source, StylesManager stylesManager, List targetColumns, - short colorIdx) { + short colorIdx) + throws XMLStreamException { Objects.requireNonNull(source); Objects.requireNonNull(stylesManager); @@ -84,7 +83,8 @@ private PaintColumnsReader( XMLEventReader source, StylesManager stylesManager, List targetColumns, - short colorIdx) { + short colorIdx) + throws XMLStreamException { super(source); @@ -127,7 +127,7 @@ protected void seekNext() throws XMLStreamException { if (StaxUtil.isStart(event, QNAME.SHEET_DATA)) { // 元ファイルに cols 要素が存在しない場合は、 // cols 要素を作成して着色列分の col 要素を追加する。 - buffer.add(eventFactory.createStartElement(QNAME.COLS, Collections.emptyIterator(), null)); + buffer.add(createStartElement(QNAME.COLS, Collections.emptyIterator())); targetRanges.forEach(this::createCol); buffer.add(eventFactory.createEndElement(QNAME.COLS, null)); auto = true; @@ -300,7 +300,7 @@ private void createCol(int start, int end) { // "9.1" を指定すると 8.47 になる。Apache POI は魔訶不識である。 attrs.add(eventFactory.createAttribute(NONS_QNAME.WIDTH, "9.1")); - buffer.add(eventFactory.createStartElement(QNAME.COL, attrs.iterator(), null)); + buffer.add(createStartElement(QNAME.COL, attrs.iterator())); buffer.add(eventFactory.createEndElement(QNAME.COL, null)); } @@ -349,6 +349,6 @@ private StartElement modifyCol(StartElement original, int start, int end, boolea } } - return eventFactory.createStartElement(QNAME.COL, newAttrs.values().iterator(), null); + return createStartElement(QNAME.COL, newAttrs.values().iterator()); } } diff --git a/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/logic/stax/readers/PaintDiffCellsReader.java b/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/logic/stax/readers/PaintDiffCellsReader.java index 9931524b..da0f3ccd 100644 --- a/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/logic/stax/readers/PaintDiffCellsReader.java +++ b/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/logic/stax/readers/PaintDiffCellsReader.java @@ -14,7 +14,6 @@ import java.util.stream.Collectors; import javax.xml.namespace.QName; -import javax.xml.stream.XMLEventFactory; import javax.xml.stream.XMLEventReader; import javax.xml.stream.XMLStreamException; import javax.xml.stream.events.Attribute; @@ -40,8 +39,6 @@ public class PaintDiffCellsReader extends BufferingReader { // [static members] ******************************************************** - private static final XMLEventFactory eventFactory = XMLEventFactory.newFactory(); - private static final Comparator cellSorter = (c1, c2) -> { if (c1.row() != c2.row()) { return c1.row() < c2.row() ? -1 : 1; @@ -60,6 +57,7 @@ public class PaintDiffCellsReader extends BufferingReader { * @param diffCellContents 差分セル * @param colorIdx 着色する色のインデックス * @return 新しいリーダー + * @throws XMLStreamException XMLイベントの解析に失敗した場合 * @throws NullPointerException パラメータが {@code null} の場合 * @throws IllegalArgumentException {@code diffCellContents} が空の場合 */ @@ -67,7 +65,8 @@ public static XMLEventReader of( XMLEventReader source, StylesManager stylesManager, List diffCellContents, - short colorIdx) { + short colorIdx) + throws XMLStreamException { Objects.requireNonNull(source); Objects.requireNonNull(stylesManager); @@ -95,7 +94,8 @@ private PaintDiffCellsReader( XMLEventReader source, StylesManager stylesManager, List diffCellContents, - short colorIdx) { + short colorIdx) + throws XMLStreamException { super(source); @@ -227,7 +227,7 @@ private Queue> groupingCEvents() throws XMLStreamException { private void createRowStart(int r) { Set attrs = new HashSet<>(); attrs.add(eventFactory.createAttribute(NONS_QNAME.R, Integer.toString(r + 1))); - buffer.add(eventFactory.createStartElement(QNAME.ROW, attrs.iterator(), null)); + buffer.add(createStartElement(QNAME.ROW, attrs.iterator())); } /** @@ -249,7 +249,7 @@ private void createCell(String addr) { attrs.add(eventFactory.createAttribute(NONS_QNAME.R, addr)); attrs.add(eventFactory.createAttribute(NONS_QNAME.S, Integer.toString(newStyle))); - buffer.add(eventFactory.createStartElement(QNAME.C, attrs.iterator(), null)); + buffer.add(createStartElement(QNAME.C, attrs.iterator())); buffer.add(eventFactory.createEndElement(QNAME.C, null)); } @@ -280,6 +280,6 @@ private StartElement paintCell(StartElement original) { } } - return eventFactory.createStartElement(QNAME.C, newAttrs.values().iterator(), null); + return createStartElement(QNAME.C, newAttrs.values().iterator()); } } diff --git a/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/logic/stax/readers/PaintDiffOrRedundantCommentsReader.java b/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/logic/stax/readers/PaintDiffOrRedundantCommentsReader.java index feea40f0..50f3111a 100644 --- a/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/logic/stax/readers/PaintDiffOrRedundantCommentsReader.java +++ b/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/logic/stax/readers/PaintDiffOrRedundantCommentsReader.java @@ -8,7 +8,6 @@ import java.util.Set; import javax.xml.namespace.QName; -import javax.xml.stream.XMLEventFactory; import javax.xml.stream.XMLEventReader; import javax.xml.stream.XMLStreamException; import javax.xml.stream.events.Attribute; @@ -34,8 +33,6 @@ public class PaintDiffOrRedundantCommentsReader extends BufferingReader { // [static members] ******************************************************** - private static final XMLEventFactory eventFactory = XMLEventFactory.newFactory(); - /** * 新しいリーダーを構成します。
* @@ -45,6 +42,7 @@ public class PaintDiffOrRedundantCommentsReader extends BufferingReader { * @param diffCommentColor 差分セルコメントに適用する色 * @param redundantCommentColor 余剰セルコメントに適用する色 * @return 新しいリーダー + * @throws XMLStreamException XMLイベントの解析に失敗した場合 * @throws NullPointerException パラメータが {@code null} の場合 * @throws IllegalArgumentException * {@code diffCommentAddrs}, @@ -55,7 +53,8 @@ public static XMLEventReader of( Set diffCommentAddrs, Set redundantCommentAddrs, String diffCommentColor, - String redundantCommentColor) { + String redundantCommentColor) + throws XMLStreamException { Objects.requireNonNull(source); Objects.requireNonNull(diffCommentAddrs); @@ -91,7 +90,8 @@ private PaintDiffOrRedundantCommentsReader( Set diffCommentAddrs, Set redundantCommentAddrs, String diffCommentColor, - String redundantCommentColor) { + String redundantCommentColor) + throws XMLStreamException { super(source); @@ -176,7 +176,7 @@ private void processCommentShape(Queue events, String color) { buffer.add(events.poll()); } - buffer.add(eventFactory.createStartElement(X_QNAME.VISIBLE, null, null)); + buffer.add(createStartElement(X_QNAME.VISIBLE, null)); buffer.add(eventFactory.createEndElement(X_QNAME.VISIBLE, null)); buffer.addAll(events); @@ -192,6 +192,6 @@ private StartElement createNewShape(StartElement originalShape, String color) { attrs.put(NONS_QNAME.FILL_COLOR, eventFactory.createAttribute(NONS_QNAME.FILL_COLOR, color)); - return eventFactory.createStartElement(V_QNAME.SHAPE, attrs.values().iterator(), null); + return createStartElement(V_QNAME.SHAPE, attrs.values().iterator()); } } diff --git a/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/logic/stax/readers/PaintRedundantCellsReader.java b/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/logic/stax/readers/PaintRedundantCellsReader.java index e1f36ccd..1ee6d52f 100644 --- a/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/logic/stax/readers/PaintRedundantCellsReader.java +++ b/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/logic/stax/readers/PaintRedundantCellsReader.java @@ -9,7 +9,6 @@ import java.util.Set; import javax.xml.namespace.QName; -import javax.xml.stream.XMLEventFactory; import javax.xml.stream.XMLEventReader; import javax.xml.stream.XMLStreamException; import javax.xml.stream.events.Attribute; @@ -35,8 +34,6 @@ public class PaintRedundantCellsReader extends BufferingReader { // [static members] ******************************************************** - private static final XMLEventFactory eventFactory = XMLEventFactory.newFactory(); - /** * 新しいリーダーを構成します。
* @@ -46,6 +43,7 @@ public class PaintRedundantCellsReader extends BufferingReader { * @param redundantColumns 余剰列インデックス(0 開始) * @param colorIdx 着色する色のインデックス * @return 新しいリーダー + * @throws XMLStreamException XMLイベントの解析に失敗した場合 * @throws NullPointerException パラメータが {@code null} の場合 * @throws IllegalArgumentException * {@code redundantRows}, @@ -56,7 +54,8 @@ public static XMLEventReader of( StylesManager stylesManager, List redundantRows, List redundantColumns, - short colorIdx) { + short colorIdx) + throws XMLStreamException { Objects.requireNonNull(source); Objects.requireNonNull(stylesManager); @@ -86,7 +85,8 @@ private PaintRedundantCellsReader( StylesManager stylesManager, List redundantRows, List redundantColumns, - short colorIdx) { + short colorIdx) + throws XMLStreamException { super(source); @@ -147,6 +147,6 @@ private StartElement paintCell(StartElement original) { } } - return eventFactory.createStartElement(QNAME.C, newAttrs.values().iterator(), null); + return createStartElement(QNAME.C, newAttrs.values().iterator()); } } diff --git a/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/logic/stax/readers/PaintRowsReader.java b/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/logic/stax/readers/PaintRowsReader.java index 264dd263..e3b3e681 100644 --- a/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/logic/stax/readers/PaintRowsReader.java +++ b/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/logic/stax/readers/PaintRowsReader.java @@ -12,7 +12,6 @@ import java.util.Set; import javax.xml.namespace.QName; -import javax.xml.stream.XMLEventFactory; import javax.xml.stream.XMLEventReader; import javax.xml.stream.XMLStreamException; import javax.xml.stream.events.Attribute; @@ -36,8 +35,6 @@ public class PaintRowsReader extends BufferingReader { // [static members] ******************************************************** - private static final XMLEventFactory eventFactory = XMLEventFactory.newFactory(); - /** * 新しいリーダーを構成します。
* @@ -46,6 +43,7 @@ public class PaintRowsReader extends BufferingReader { * @param targetRows 着色対象の行インデックス(0 開始) * @param colorIdx 着色する色のインデックス * @return 新しいリーダー + * @throws XMLStreamException XMLイベントの解析に失敗した場合 * @throws NullPointerException パラメータが {@code null} の場合 * @throws IllegalArgumentException {@code targetRows} の長さが 0 の場合 */ @@ -53,7 +51,8 @@ public static XMLEventReader of( XMLEventReader source, StylesManager stylesManager, List targetRows, - short colorIdx) { + short colorIdx) + throws XMLStreamException { Objects.requireNonNull(source); Objects.requireNonNull(stylesManager); @@ -80,7 +79,8 @@ private PaintRowsReader( XMLEventReader source, StylesManager stylesManager, List targetRows, - short colorIdx) { + short colorIdx) + throws XMLStreamException { super(source); @@ -150,7 +150,7 @@ private void createRow(int r) { attrs.add(eventFactory.createAttribute(NONS_QNAME.S, Integer.toString(newStyle))); attrs.add(eventFactory.createAttribute(NONS_QNAME.CUSTOM_FORMAT, "1")); - buffer.add(eventFactory.createStartElement(QNAME.ROW, attrs.iterator(), null)); + buffer.add(createStartElement(QNAME.ROW, attrs.iterator())); buffer.add(eventFactory.createEndElement(QNAME.ROW, null)); } @@ -184,7 +184,7 @@ private StartElement paintRow(StartElement original) { } } - return eventFactory.createStartElement(QNAME.ROW, newAttrs.values().iterator(), null); + return createStartElement(QNAME.ROW, newAttrs.values().iterator()); } /** @@ -203,6 +203,6 @@ private StartElement removeCustomFormat(StartElement original) { } } - return eventFactory.createStartElement(QNAME.ROW, attrs.iterator(), null); + return createStartElement(QNAME.ROW, attrs.iterator()); } } diff --git a/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/logic/stax/readers/PaintSheetTabReader.java b/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/logic/stax/readers/PaintSheetTabReader.java index c205a9c6..22958d5e 100644 --- a/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/logic/stax/readers/PaintSheetTabReader.java +++ b/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/logic/stax/readers/PaintSheetTabReader.java @@ -5,7 +5,6 @@ import java.util.Objects; import java.util.Set; -import javax.xml.stream.XMLEventFactory; import javax.xml.stream.XMLEventReader; import javax.xml.stream.XMLStreamException; import javax.xml.stream.events.Attribute; @@ -28,19 +27,19 @@ public class PaintSheetTabReader extends BufferingReader { // [static members] ******************************************************** - private static final XMLEventFactory eventFactory = XMLEventFactory.newFactory(); - /** * 新しいリーダーを構成します。
* * @param source ソースリーダー * @param color 着色する色 * @return 新しいリーダー + * @throws XMLStreamException XMLイベントの解析に失敗した場合 * @throws NullPointerException パラメータが {@code null} の場合 */ public static XMLEventReader of( XMLEventReader source, - Color color) { + Color color) + throws XMLStreamException { Objects.requireNonNull(source); Objects.requireNonNull(color); @@ -55,7 +54,8 @@ public static XMLEventReader of( private PaintSheetTabReader( XMLEventReader source, - Color color) { + Color color) + throws XMLStreamException { super(source); @@ -80,10 +80,10 @@ protected void seekNext() throws XMLStreamException { } buffer.add(source.nextEvent()); - buffer.add(eventFactory.createStartElement(QNAME.SHEET_PR, Collections.emptyIterator(), null)); + buffer.add(createStartElement(QNAME.SHEET_PR, Collections.emptyIterator())); Set attrs = Set.of(eventFactory.createAttribute(NONS_QNAME.RGB, rgb)); - buffer.add(eventFactory.createStartElement(QNAME.TAB_COLOR, attrs.iterator(), null)); + buffer.add(createStartElement(QNAME.TAB_COLOR, attrs.iterator())); buffer.add(eventFactory.createEndElement(QNAME.TAB_COLOR, null)); buffer.add(eventFactory.createEndElement(QNAME.SHEET_PR, null)); diff --git a/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/tasks/CompareTask.java b/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/tasks/CompareTask.java index 266d5ad0..768ab9c4 100644 --- a/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/tasks/CompareTask.java +++ b/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/tasks/CompareTask.java @@ -204,15 +204,10 @@ protected void paintSaveAndShowBook( int progressAfter) throws ApplicationException { - try { - if (isSameBook()) { - paintSaveAndShowBook1(workDir, srcBookPathPair.a(), bResult, 80, 98); - } else { - paintSaveAndShowBook2(workDir, srcBookPathPair, bResult, 80, 98); - } - - } catch (Exception e) { - throw getApplicationException(e, "AppTaskBase.180", " at AppTaskBase::paintSaveAndShowBook"); + if (isSameBook()) { + paintSaveAndShowBook1(workDir, srcBookPathPair.a(), bResult, 80, 98); + } else { + paintSaveAndShowBook2(workDir, srcBookPathPair, bResult, 80, 98); } } @@ -236,6 +231,7 @@ private void paintSaveAndShowBook1( throws ApplicationException { Path dstBookPath = null; + ApplicationException thrown = null; try { updateProgress(progressBefore, PROGRESS_MAX); @@ -257,7 +253,7 @@ private void paintSaveAndShowBook1( updateProgress(progressBefore + (progressAfter - progressBefore) * 4 / 5, PROGRESS_MAX); } catch (Exception e) { - throw getApplicationException(e, "AppTaskBase.070", ""); + thrown = getApplicationException(e, "AppTaskBase.070", ""); } try { @@ -270,7 +266,16 @@ private void paintSaveAndShowBook1( updateProgress(progressAfter, PROGRESS_MAX); } catch (Exception e) { - throw getApplicationException(e, "AppTaskBase.090", ""); + ApplicationException ee = getApplicationException(e, "AppTaskBase.090", ""); + if (thrown == null) { + thrown = ee; + } else { + thrown.addSuppressed(ee); + } + } + + if (thrown != null) { + throw thrown; } } @@ -293,6 +298,8 @@ private void paintSaveAndShowBook2( int progressAfter) throws ApplicationException { + ApplicationException thrown = null; + try { updateProgress(progressBefore, PROGRESS_MAX); str.append(rb.getString("AppTaskBase.060")).append(BR); @@ -321,7 +328,13 @@ private void paintSaveAndShowBook2( PROGRESS_MAX); } catch (Exception e) { - throw getApplicationException(e, side == Side.A ? "AppTaskBase.100" : "AppTaskBase.110", ""); + ApplicationException ee = getApplicationException(e, + side == Side.A ? "AppTaskBase.100" : "AppTaskBase.110", ""); + if (thrown == null) { + thrown = ee; + } else { + thrown.addSuppressed(ee); + } } } @@ -337,7 +350,16 @@ private void paintSaveAndShowBook2( updateProgress(progressAfter, PROGRESS_MAX); } catch (Exception e) { - throw getApplicationException(e, "AppTaskBase.090", ""); + ApplicationException ee = getApplicationException(e, "AppTaskBase.090", ""); + if (thrown == null) { + thrown = ee; + } else { + thrown.addSuppressed(ee); + } + } + + if (thrown != null) { + throw thrown; } } diff --git a/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/tasks/CompareTaskDirs.java b/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/tasks/CompareTaskDirs.java index e86855c5..6cd20cf0 100644 --- a/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/tasks/CompareTaskDirs.java +++ b/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/tasks/CompareTaskDirs.java @@ -38,7 +38,8 @@ public final class CompareTaskDirs extends CompareTask { /** * コンストラクタ * - * @param settings 設定セット + * @param settings + * 設定セット */ public CompareTaskDirs(Settings settings) { super(settings); @@ -179,7 +180,7 @@ private ResultOfDirs compareDirs( pairingInfoDirs, pairingInfoDirs.childBookInfoPairs().stream().collect(Collectors.toMap( Function.identity(), - name -> Optional.empty())), + _ -> Optional.empty())), ""); } diff --git a/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/util/NetUtil.java b/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/util/NetUtil.java new file mode 100644 index 00000000..d172258b --- /dev/null +++ b/xyz.hotchpotch.hogandiff/src/main/java/xyz/hotchpotch/hogandiff/util/NetUtil.java @@ -0,0 +1,52 @@ +package xyz.hotchpotch.hogandiff.util; + +import java.util.Objects; + +import org.json.JSONObject; + +import com.google.api.client.http.GenericUrl; +import com.google.api.client.http.HttpRequest; +import com.google.api.client.http.HttpRequestFactory; +import com.google.api.client.http.HttpResponse; +import com.google.api.client.http.javanet.NetHttpTransport; + +/** + * ネットワーク関連のユーティリティクラスです。
+ * + * @author nmby + */ +public class NetUtil { + + // [static members] ******************************************************** + + private static final HttpRequestFactory requestFactory = new NetHttpTransport().createRequestFactory(); + + /** + * 指定されたURLにGETリクエストを送り、レスポンスボディをJSONオブジェクトとして返します。
+ * + * @param url URL + * @return JSONオブジェクト + * @throws NullPointerException 引数に {@code null} が指定された場合 + */ + public static JSONObject getAsJson(String url) { + Objects.requireNonNull(url); + + try { + HttpRequest request = requestFactory.buildGetRequest(new GenericUrl(url)); + request.setConnectTimeout(5000); + request.setReadTimeout(5000); + + HttpResponse response = request.execute(); + String jsonString = response.parseAsString(); + return new JSONObject(jsonString); + + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + // [instance members] ****************************************************** + + private NetUtil() { + } +} diff --git a/xyz.hotchpotch.hogandiff/src/main/resources/messages.properties b/xyz.hotchpotch.hogandiff/src/main/resources/messages.properties index 7b9cdef6..f3b5ae85 100644 --- a/xyz.hotchpotch.hogandiff/src/main/resources/messages.properties +++ b/xyz.hotchpotch.hogandiff/src/main/resources/messages.properties @@ -23,6 +23,7 @@ fx.SettingsPane1.execute.040=精度優先 fx.SettingsPane2.010=言語 fx.SettingsPane2.020=作業用\nフォルダ fx.SettingsPane2.030=統計情報の収集に協力する +fx.SettingsPane2.040=詳細設定… fx.SettingsPane2.workDir.010=開く fx.SettingsPane2.workDir.020=変更... fx.SettingsPane2.workDir.030=削除... @@ -41,6 +42,13 @@ fx.GoogleFilePickerDialogPane.090=スター付き fx.GoogleFilePickerDialogPane.100=最近使ったファイル fx.GooglePane.010=Googleドライブ\n連携 fx.GooglePane.020=Googleドライブ\n連携解除 +fx.GoogleRevisionSelectorDialog.010=Googleドライブからのファイルダウンロードに失敗しました。 +fx.SettingDetailsDialogPane.010=更新確認 +fx.SettingDetailsDialogPane.020=起動時に新規バージョンの有無を確認する +fx.SettingDetailsDialogPane.030=新規バージョンの有無を今すぐ確認する +fx.SettingDetailsDialogPane.040=設定 +fx.SettingDetailsDialogPane.050=設定ファイルを表示する +fx.SettingDetailsDialogPane.060=設定をリセットする… excel.poi.usermodel.TreeResultBookCreator.010=比較フォルダ%s: excel.poi.usermodel.TreeResultBookCreator.020=作業用フォルダ: @@ -64,6 +72,9 @@ gui.MainController.060=作業用フォルダの変更 gui.MainController.070=処理を中止しました。 gui.PasswordDialog.010=パスワード指定 gui.PasswordDialogPane.010=%s はパスワードで保護されています。 +gui.UpdateChecker.010=新しいバージョンが利用可能です。 +gui.UpdateChecker.020=新しいバージョンが利用可能です。\n\n - 現在のバージョン : %s\n - 最新のバージョン : %s\n\n最新バージョンをダウンロードするには、Webサイトをご確認ください。 +gui.UpdateChecker.030=お使いのアプリケーションは最新バージョンです。\n - 現在のバージョン : %s gui.component.LinkPane.010=Webページの表示に失敗しました。ご利用のブラウザでお試しください。 gui.component.MenuPane.010=現在のバージョンでは未対応です。\n将来のバージョンにご期待ください! @@ -74,6 +85,7 @@ gui.component.SettingsPane2.040=次のフォルダの内容物を全て削除し gui.component.SettingsPane2.051=表示言語の変更を保存しました。\nアプリケーションを再起動すると変更が反映されます。 gui.component.SettingsPane2.052=Display language change is saved. \nRestart the application to reflect the change. gui.component.SettingsPane2.053=对显示语言的改变已经被保存。\n重新启动应用程序,这些变化就会生效。 +gui.component.SettingsPane2.060=方眼Diff - 詳細設定 gui.component.TargetSelectionPane.010=比較対象フォルダの選択 gui.component.TargetSelectionPane.020=比較対象ブックの選択 gui.component.TargetSelectionPane.030=Excel ブック @@ -93,6 +105,8 @@ gui.component.GooglePane.090=Googleドライブからファイルをダウンロ gui.component.GooglePane.100=選択されたファイルをGoogleドライブからダウンロードしてこのPCの下記リンク先フォルダに保存しました。\nPC上に保存された状態が好ましくない場合は、比較処理が終わり次第、ご自身で削除してください。 gui.component.GooglePane.110=次回以降、このメッセージを表示しない +gui.dialogs.SettingDetailsDialogPane.010=設定を初期化しアプリケーションを終了します。\nよろしいですか? + AppMain.010=方眼Diff AppResource.010=設定の保存に失敗しました。 diff --git a/xyz.hotchpotch.hogandiff/src/main/resources/messages_en.properties b/xyz.hotchpotch.hogandiff/src/main/resources/messages_en.properties index 15b59a74..b8e77bbe 100644 --- a/xyz.hotchpotch.hogandiff/src/main/resources/messages_en.properties +++ b/xyz.hotchpotch.hogandiff/src/main/resources/messages_en.properties @@ -23,6 +23,7 @@ fx.SettingsPane1.execute.040=Prioritize accuracy fx.SettingsPane2.010=Language fx.SettingsPane2.020=Working directory fx.SettingsPane2.030=Allow usage data collection +fx.SettingsPane2.040=Advanced Settings… fx.SettingsPane2.workDir.010=Open fx.SettingsPane2.workDir.020=Change... fx.SettingsPane2.workDir.030=Delete... @@ -41,6 +42,13 @@ fx.GoogleFilePickerDialogPane.090=Starred fx.GoogleFilePickerDialogPane.100=Recently picked fx.GooglePane.010=Connect\nGoogle Drive fx.GooglePane.020=Disconnect\nGoogle Drive +fx.GoogleRevisionSelectorDialog.010=Failed to download the file from Google Drive. +fx.SettingDetailsDialogPane.010=Update Check +fx.SettingDetailsDialogPane.020=Check for new versions at startup +fx.SettingDetailsDialogPane.030=Check for new versions now +fx.SettingDetailsDialogPane.040=Settings +fx.SettingDetailsDialogPane.050=Display the configuration file +fx.SettingDetailsDialogPane.060=Reset settings… excel.poi.usermodel.TreeResultBookCreator.010=Folder %s : excel.poi.usermodel.TreeResultBookCreator.020=Working dir : @@ -64,6 +72,9 @@ gui.MainController.060=Change working directory gui.MainController.070=Processing has been canceled. gui.PasswordDialog.010=Enter Password gui.PasswordDialogPane.010=The book [%s] is password protected. +gui.UpdateChecker.010=A new version is available. +gui.UpdateChecker.020=A new version is available.\n\n - Current version : %s\n - Latest version : %s\n\nTo download the latest version, please visit: +gui.UpdateChecker.030=Your application is up to date.\n - Current version : %s gui.component.LinkPane.010=Failed to open the website. Please try using your browser. gui.component.MenuPane.010=This is not supported in the current version.\nStay tuned for future versions! @@ -74,6 +85,7 @@ gui.component.SettingsPane2.040=Delete all contents of the following directory. gui.component.SettingsPane2.051=表示言語の変更を保存しました。\nアプリケーションを再起動すると変更が反映されます。 gui.component.SettingsPane2.052=Display language change is saved. \nRestart the application to reflect the change. gui.component.SettingsPane2.053=对显示语言的改变已经被保存。\n重新启动应用程序,这些变化就会生效。 +gui.component.SettingsPane2.060=HoganDiff - Advanced Settings gui.component.TargetSelectionPane.010=Select comparison folder gui.component.TargetSelectionPane.020=Select comparison book gui.component.TargetSelectionPane.030=Excel book @@ -93,6 +105,8 @@ gui.component.GooglePane.090=File downloaded from Google Drive gui.component.GooglePane.100=The selected file has been downloaded from Google Drive and saved to the folder linked below on this PC.\nIf you prefer not to keep the file stored on your PC, please delete it manually after the comparison process is complete. gui.component.GooglePane.110=Don't show this message again +gui.dialogs.SettingDetailsDialogPane.010=Initialize settings and exit the application.\nAre you sure? + AppMain.010=HoganDiff (方眼Diff) AppResource.010=Failed to save settings. diff --git a/xyz.hotchpotch.hogandiff/src/main/resources/messages_zh.properties b/xyz.hotchpotch.hogandiff/src/main/resources/messages_zh.properties index 9706c0ee..45558d1d 100644 --- a/xyz.hotchpotch.hogandiff/src/main/resources/messages_zh.properties +++ b/xyz.hotchpotch.hogandiff/src/main/resources/messages_zh.properties @@ -23,6 +23,7 @@ fx.SettingsPane1.execute.040=优先考虑准确性 fx.SettingsPane2.010=语言 fx.SettingsPane2.020=工作\n文件夹 fx.SettingsPane2.030=同意收集使用统计信息 +fx.SettingsPane2.040=详细设置... fx.SettingsPane2.workDir.010=打开 fx.SettingsPane2.workDir.020=改变... fx.SettingsPane2.workDir.030=删除... @@ -41,6 +42,13 @@ fx.GoogleFilePickerDialogPane.090=已加星标 fx.GoogleFilePickerDialogPane.100=最近使用的文件 fx.GooglePane.010=Google Drive\n关联 fx.GooglePane.020=Google Drive\n关联解除 +fx.GoogleRevisionSelectorDialog.010=从Google云端硬盘下载文件失败。 +fx.SettingDetailsDialogPane.010=更新确认 +fx.SettingDetailsDialogPane.020=启动时检查是否有新版本 +fx.SettingDetailsDialogPane.030=立即检查是否有新版本 +fx.SettingDetailsDialogPane.040=设置 +fx.SettingDetailsDialogPane.050=显示配置文件 +fx.SettingDetailsDialogPane.060=重置设置… excel.poi.usermodel.TreeResultBookCreator.010=文件夹%s: excel.poi.usermodel.TreeResultBookCreator.020=工作文件夹: @@ -64,6 +72,9 @@ gui.MainController.060=改变工作文件夹 gui.MainController.070=处理已被取消。 gui.PasswordDialog.010=输入密码 gui.PasswordDialogPane.010=%s 是受密码保护的。 +gui.UpdateChecker.010=有新版本可用。 +gui.UpdateChecker.020=有新版本可用。\n\n - 当前版本 : %s\n - 最新版本 : %s\n\n要下载最新版本,请访问: +gui.UpdateChecker.030=您的应用程序已是最新版本。\n - 当前版本 : %s gui.component.LinkPane.010=网页未能显示。 请尝试使用你的浏览器。 gui.component.MenuPane.010=当前版本不支持此功能。\n请继续关注未来版本! @@ -74,6 +85,7 @@ gui.component.SettingsPane2.040=删除以下文件夹的所有内容。你确定 gui.component.SettingsPane2.051=表示言語の変更を保存しました。\nアプリケーションを再起動すると変更が反映されます。 gui.component.SettingsPane2.052=Display language change is saved. \nRestart the application to reflect the change. gui.component.SettingsPane2.053=对显示语言的改变已经被保存。\n重新启动应用程序,这些变化就会生效。 +gui.component.SettingsPane2.060=方眼Diff - 详细设置 gui.component.TargetSelectionPane.010=选择用于比较的文件夹 gui.component.TargetSelectionPane.020=选择用于比较的工作簿 gui.component.TargetSelectionPane.030=Excel工作簿 @@ -93,6 +105,8 @@ gui.component.GooglePane.090=已从Google云端硬盘下载文件 gui.component.GooglePane.100=已从Google云端硬盘下载所选文件,并保存到本机下方链接的文件夹中。\n如果您不希望文件保存在电脑上,请在比较处理完成后自行删除。 gui.component.GooglePane.110=不再显示此消息 +gui.dialogs.SettingDetailsDialogPane.010=初始化设置并退出应用程序。\n确定吗? + AppMain.010=方眼Diff AppResource.010=保存设置失败。 diff --git a/xyz.hotchpotch.hogandiff/src/main/resources/xyz/hotchpotch/hogandiff/gui/application.css b/xyz.hotchpotch.hogandiff/src/main/resources/xyz/hotchpotch/hogandiff/gui/application.css index 910c0b5a..ed09fd11 100644 --- a/xyz.hotchpotch.hogandiff/src/main/resources/xyz/hotchpotch/hogandiff/gui/application.css +++ b/xyz.hotchpotch.hogandiff/src/main/resources/xyz/hotchpotch/hogandiff/gui/application.css @@ -87,6 +87,17 @@ -fx-pref-width: 65.0px; } +.detailsPane { + -fx-background-color: rgb(230.0, 240.0, 255.0); + -fx-spacing: 3.0px; +} + +.detailsTitleLabel { + -fx-background-color: rgb(196.0, 219.0, 255.0); + -fx-padding: 0.0px 7.0px 0.0px 5.0px; + -fx-pref-width: 99.0px; +} + .localeComboBox { -fx-pref-width: 70.0px; } diff --git a/xyz.hotchpotch.hogandiff/src/main/resources/xyz/hotchpotch/hogandiff/gui/components/SettingsPane2.fxml b/xyz.hotchpotch.hogandiff/src/main/resources/xyz/hotchpotch/hogandiff/gui/components/SettingsPane2.fxml index f3c231d2..7ca613c3 100644 --- a/xyz.hotchpotch.hogandiff/src/main/resources/xyz/hotchpotch/hogandiff/gui/components/SettingsPane2.fxml +++ b/xyz.hotchpotch.hogandiff/src/main/resources/xyz/hotchpotch/hogandiff/gui/components/SettingsPane2.fxml @@ -2,115 +2,55 @@ - - + - - + + - - + + - + + + - - - - - - - - - - - - - - - - - + + + + diff --git a/xyz.hotchpotch.hogandiff/src/main/resources/xyz/hotchpotch/hogandiff/gui/dialogs/SettingDetailsDialogPane.fxml b/xyz.hotchpotch.hogandiff/src/main/resources/xyz/hotchpotch/hogandiff/gui/dialogs/SettingDetailsDialogPane.fxml new file mode 100644 index 00000000..32e96e3c --- /dev/null +++ b/xyz.hotchpotch.hogandiff/src/main/resources/xyz/hotchpotch/hogandiff/gui/dialogs/SettingDetailsDialogPane.fxml @@ -0,0 +1,83 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/xyz.hotchpotch.hogandiff/src/test/java/xyz/hotchpotch/hogandiff/core/MinimumEditDistanceMatcherTest.java b/xyz.hotchpotch.hogandiff/src/test/java/xyz/hotchpotch/hogandiff/core/MinimumEditDistanceMatcherTest.java index 2bde414b..b37f265c 100644 --- a/xyz.hotchpotch.hogandiff/src/test/java/xyz/hotchpotch/hogandiff/core/MinimumEditDistanceMatcherTest.java +++ b/xyz.hotchpotch.hogandiff/src/test/java/xyz/hotchpotch/hogandiff/core/MinimumEditDistanceMatcherTest.java @@ -15,7 +15,7 @@ class MinimumEditDistanceMatcherTest { // [static members] ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - private static final ToIntFunction gapEvaluator = c -> 1; + private static final ToIntFunction gapEvaluator = _ -> 1; private static final ToIntBiFunction diffEvaluator = (c1, c2) -> c1.equals(c2) ? 0 : 3; private static final List list0_1 = List.of(); diff --git a/xyz.hotchpotch.hogandiff/src/test/java/xyz/hotchpotch/hogandiff/logic/plain/SheetNamesLoaderCombinedTest.java b/xyz.hotchpotch.hogandiff/src/test/java/xyz/hotchpotch/hogandiff/logic/plain/BookInfoLoaderCombinedTest.java similarity index 66% rename from xyz.hotchpotch.hogandiff/src/test/java/xyz/hotchpotch/hogandiff/logic/plain/SheetNamesLoaderCombinedTest.java rename to xyz.hotchpotch.hogandiff/src/test/java/xyz/hotchpotch/hogandiff/logic/plain/BookInfoLoaderCombinedTest.java index 756d72e5..4504f472 100644 --- a/xyz.hotchpotch.hogandiff/src/test/java/xyz/hotchpotch/hogandiff/logic/plain/SheetNamesLoaderCombinedTest.java +++ b/xyz.hotchpotch.hogandiff/src/test/java/xyz/hotchpotch/hogandiff/logic/plain/BookInfoLoaderCombinedTest.java @@ -8,17 +8,17 @@ import org.junit.jupiter.api.Test; import xyz.hotchpotch.hogandiff.logic.BookInfo; +import xyz.hotchpotch.hogandiff.logic.BookInfoLoader; import xyz.hotchpotch.hogandiff.logic.ExcelHandlingException; -import xyz.hotchpotch.hogandiff.logic.SheetNamesLoader; -class SheetNamesLoaderCombinedTest { +class BookInfoLoaderCombinedTest { // [static members] ******************************************************** - private static final SheetNamesLoader successLoader = (bookPath, readPassword) -> BookInfo.ofLoadCompleted( + private static final BookInfoLoader successLoader = (bookPath, _) -> BookInfo.ofLoadCompleted( bookPath, List.of("success")); - private static final SheetNamesLoader failLoader = (bookPath, readPassword) -> { + private static final BookInfoLoader failLoader = (_, _) -> { throw new RuntimeException("fail"); }; @@ -29,24 +29,24 @@ void testOf() { // 異常系 assertThrows( NullPointerException.class, - () -> SheetNamesLoaderCombined.of(null)); + () -> BookInfoLoaderCombined.of(null)); assertThrows( IllegalArgumentException.class, - () -> SheetNamesLoaderCombined.of(List.of())); + () -> BookInfoLoaderCombined.of(List.of())); // 正常系 assertTrue( - SheetNamesLoaderCombined.of(List.of( - () -> successLoader)) instanceof SheetNamesLoaderCombined); + BookInfoLoaderCombined.of(List.of( + () -> successLoader)) instanceof BookInfoLoaderCombined); assertTrue( - SheetNamesLoaderCombined.of(List.of( + BookInfoLoaderCombined.of(List.of( () -> successLoader, - () -> failLoader)) instanceof SheetNamesLoaderCombined); + () -> failLoader)) instanceof BookInfoLoaderCombined); } @Test void testLoadSheetNames_パラメータチェック() { - SheetNamesLoader testee = SheetNamesLoaderCombined.of(List.of(() -> successLoader)); + BookInfoLoader testee = BookInfoLoaderCombined.of(List.of(() -> successLoader)); // null パラメータ assertThrows( @@ -56,8 +56,8 @@ void testOf() { @Test void testLoadSheetNames_失敗系() { - SheetNamesLoader testeeF = SheetNamesLoaderCombined.of(List.of(() -> failLoader)); - SheetNamesLoader testeeFFF = SheetNamesLoaderCombined.of(List.of( + BookInfoLoader testeeF = BookInfoLoaderCombined.of(List.of(() -> failLoader)); + BookInfoLoader testeeFFF = BookInfoLoaderCombined.of(List.of( () -> failLoader, () -> failLoader, () -> failLoader)); // 失敗1つ @@ -73,8 +73,8 @@ void testOf() { @Test void testLoadSheetNames_成功系() throws ExcelHandlingException { - SheetNamesLoader testeeS = SheetNamesLoaderCombined.of(List.of(() -> successLoader)); - SheetNamesLoader testeeFFSF = SheetNamesLoaderCombined.of(List.of( + BookInfoLoader testeeS = BookInfoLoaderCombined.of(List.of(() -> successLoader)); + BookInfoLoader testeeFFSF = BookInfoLoaderCombined.of(List.of( () -> failLoader, () -> failLoader, () -> successLoader, diff --git a/xyz.hotchpotch.hogandiff/src/test/java/xyz/hotchpotch/hogandiff/logic/plain/CellsLoaderCombinedTest.java b/xyz.hotchpotch.hogandiff/src/test/java/xyz/hotchpotch/hogandiff/logic/plain/CellsLoaderCombinedTest.java index f7c67a0a..d3e51509 100644 --- a/xyz.hotchpotch.hogandiff/src/test/java/xyz/hotchpotch/hogandiff/logic/plain/CellsLoaderCombinedTest.java +++ b/xyz.hotchpotch.hogandiff/src/test/java/xyz/hotchpotch/hogandiff/logic/plain/CellsLoaderCombinedTest.java @@ -20,9 +20,9 @@ class CellsLoaderCombinedTest { private static final CellData cell1 = new CellData(1, 2, "success", null); - private static final CellsLoader successLoader = (bookPath, readPassword, sheetName) -> Set.of(cell1); + private static final CellsLoader successLoader = (_, _, _) -> Set.of(cell1); - private static final CellsLoader failLoader = (bookPath, readPassword, sheetName) -> { + private static final CellsLoader failLoader = (_, _, _) -> { throw new RuntimeException("fail"); }; diff --git a/xyz.hotchpotch.hogandiff/src/test/java/xyz/hotchpotch/hogandiff/logic/poi/SheetNamesLoaderWithPoiEventApiTest.java b/xyz.hotchpotch.hogandiff/src/test/java/xyz/hotchpotch/hogandiff/logic/poi/BookInfoLoaderWithPoiEventApiTest.java similarity index 73% rename from xyz.hotchpotch.hogandiff/src/test/java/xyz/hotchpotch/hogandiff/logic/poi/SheetNamesLoaderWithPoiEventApiTest.java rename to xyz.hotchpotch.hogandiff/src/test/java/xyz/hotchpotch/hogandiff/logic/poi/BookInfoLoaderWithPoiEventApiTest.java index 3cce9332..c7001b61 100644 --- a/xyz.hotchpotch.hogandiff/src/test/java/xyz/hotchpotch/hogandiff/logic/poi/SheetNamesLoaderWithPoiEventApiTest.java +++ b/xyz.hotchpotch.hogandiff/src/test/java/xyz/hotchpotch/hogandiff/logic/poi/BookInfoLoaderWithPoiEventApiTest.java @@ -13,10 +13,10 @@ import xyz.hotchpotch.hogandiff.logic.BookInfo; import xyz.hotchpotch.hogandiff.logic.ExcelHandlingException; -import xyz.hotchpotch.hogandiff.logic.SheetNamesLoader; +import xyz.hotchpotch.hogandiff.logic.BookInfoLoader; import xyz.hotchpotch.hogandiff.logic.SheetType; -class SheetNamesLoaderWithPoiEventApiTest { +class BookInfoLoaderWithPoiEventApiTest { // [static members] ******************************************************** @@ -30,17 +30,17 @@ class SheetNamesLoaderWithPoiEventApiTest { @BeforeAll static void beforeAll() throws URISyntaxException { - test1_xls = Path.of(SheetNamesLoaderWithPoiEventApiTest.class.getResource("Test1.xls").toURI()); - test1_xlsb = Path.of(SheetNamesLoaderWithPoiEventApiTest.class.getResource("Test1.xlsb").toURI()); - test1_xlsm = Path.of(SheetNamesLoaderWithPoiEventApiTest.class.getResource("Test1.xlsm").toURI()); - test1_xlsx = Path.of(SheetNamesLoaderWithPoiEventApiTest.class.getResource("Test1.xlsx").toURI()); + test1_xls = Path.of(BookInfoLoaderWithPoiEventApiTest.class.getResource("Test1.xls").toURI()); + test1_xlsb = Path.of(BookInfoLoaderWithPoiEventApiTest.class.getResource("Test1.xlsb").toURI()); + test1_xlsm = Path.of(BookInfoLoaderWithPoiEventApiTest.class.getResource("Test1.xlsm").toURI()); + test1_xlsx = Path.of(BookInfoLoaderWithPoiEventApiTest.class.getResource("Test1.xlsx").toURI()); test2_xls = Path.of( - SheetNamesLoaderWithPoiEventApiTest.class.getResource("Test2_passwordAAA.xls").toURI()); + BookInfoLoaderWithPoiEventApiTest.class.getResource("Test2_passwordAAA.xls").toURI()); test2_xlsx = Path - .of(SheetNamesLoaderWithPoiEventApiTest.class.getResource("Test2_passwordAAA.xlsx") + .of(BookInfoLoaderWithPoiEventApiTest.class.getResource("Test2_passwordAAA.xlsx") .toURI()); test4_xls = Path - .of(SheetNamesLoaderWithPoiEventApiTest.class.getResource("Test4_containsVBModule.xls") + .of(BookInfoLoaderWithPoiEventApiTest.class.getResource("Test4_containsVBModule.xls") .toURI()); } @@ -51,20 +51,20 @@ void testOf() { // 異常系 assertThrows( NullPointerException.class, - () -> SheetNamesLoaderWithPoiEventApi.of(null)); + () -> BookInfoLoaderWithPoiEventApi.of(null)); assertThrows( IllegalArgumentException.class, - () -> SheetNamesLoaderWithPoiEventApi.of(Set.of())); + () -> BookInfoLoaderWithPoiEventApi.of(Set.of())); // 正常系 assertTrue( - SheetNamesLoaderWithPoiEventApi.of( - EnumSet.allOf(SheetType.class)) instanceof SheetNamesLoaderWithPoiEventApi); + BookInfoLoaderWithPoiEventApi.of( + EnumSet.allOf(SheetType.class)) instanceof BookInfoLoaderWithPoiEventApi); } @Test void testLoadSheetNames_例外系_非チェック例外() { - SheetNamesLoader testee = SheetNamesLoaderWithPoiEventApi.of(Set.of(SheetType.WORKSHEET)); + BookInfoLoader testee = BookInfoLoaderWithPoiEventApi.of(Set.of(SheetType.WORKSHEET)); // null パラメータ assertThrows( @@ -88,7 +88,7 @@ void testOf() { @Test void testLoadSheetNames_例外系_チェック例外() { - SheetNamesLoader testee = SheetNamesLoaderWithPoiEventApi.of(Set.of(SheetType.WORKSHEET)); + BookInfoLoader testee = BookInfoLoaderWithPoiEventApi.of(Set.of(SheetType.WORKSHEET)); // 存在しないファイル assertEquals( @@ -103,7 +103,7 @@ void testOf() { @Test void testLoadSheetNames_全てのシート種別が対象の場合() throws ExcelHandlingException { - SheetNamesLoader testee = SheetNamesLoaderWithPoiEventApi.of(EnumSet.allOf(SheetType.class)); + BookInfoLoader testee = BookInfoLoaderWithPoiEventApi.of(EnumSet.allOf(SheetType.class)); assertEquals( BookInfo.ofLoadCompleted( @@ -115,7 +115,7 @@ void testOf() { @Test void testLoadSheetNames_ワークシートのみが対象の場合() throws ExcelHandlingException { - SheetNamesLoader testee = SheetNamesLoaderWithPoiEventApi.of(EnumSet.of(SheetType.WORKSHEET)); + BookInfoLoader testee = BookInfoLoaderWithPoiEventApi.of(EnumSet.of(SheetType.WORKSHEET)); // FIXME: [No.01 シート識別不正 - HSSF] ダイアログシートもワークシートと判別されてしまう。 // どうしようもないのかしら?? @@ -129,7 +129,7 @@ void testOf() { @Test void testLoadSheetNames_グラフシートのみが対象の場合() throws ExcelHandlingException { - SheetNamesLoader testee = SheetNamesLoaderWithPoiEventApi.of(EnumSet.of(SheetType.CHART_SHEET)); + BookInfoLoader testee = BookInfoLoaderWithPoiEventApi.of(EnumSet.of(SheetType.CHART_SHEET)); assertEquals( BookInfo.ofLoadCompleted( @@ -141,7 +141,7 @@ void testOf() { @Test void testLoadSheetNames_ダイアログシートのみが対象の場合() throws ExcelHandlingException { - SheetNamesLoader testee = SheetNamesLoaderWithPoiEventApi.of(EnumSet.of(SheetType.DIALOG_SHEET)); + BookInfoLoader testee = BookInfoLoaderWithPoiEventApi.of(EnumSet.of(SheetType.DIALOG_SHEET)); // FIXME: [No.01 シート識別不正 - HSSF] ダイアログシートもワークシートと判別されてしまう。 // どうしようもないのかしら?? @@ -154,7 +154,7 @@ void testOf() { @Test void testLoadSheetNames_マクロシートのみが対象の場合() throws ExcelHandlingException { - SheetNamesLoader testee = SheetNamesLoaderWithPoiEventApi.of(EnumSet.of(SheetType.MACRO_SHEET)); + BookInfoLoader testee = BookInfoLoaderWithPoiEventApi.of(EnumSet.of(SheetType.MACRO_SHEET)); assertEquals( BookInfo.ofLoadCompleted( @@ -166,7 +166,7 @@ void testOf() { @Test void testLoadSheetNames_VBモジュールが含まれる場合() throws ExcelHandlingException { - SheetNamesLoader testee = SheetNamesLoaderWithPoiEventApi.of(EnumSet.allOf(SheetType.class)); + BookInfoLoader testee = BookInfoLoaderWithPoiEventApi.of(EnumSet.allOf(SheetType.class)); assertEquals( BookInfo.ofLoadCompleted( diff --git a/xyz.hotchpotch.hogandiff/src/test/java/xyz/hotchpotch/hogandiff/logic/poi/SheetNamesLoaderWithPoiUserApiTest.java b/xyz.hotchpotch.hogandiff/src/test/java/xyz/hotchpotch/hogandiff/logic/poi/BookInfoLoaderWithPoiUserApiTest.java similarity index 90% rename from xyz.hotchpotch.hogandiff/src/test/java/xyz/hotchpotch/hogandiff/logic/poi/SheetNamesLoaderWithPoiUserApiTest.java rename to xyz.hotchpotch.hogandiff/src/test/java/xyz/hotchpotch/hogandiff/logic/poi/BookInfoLoaderWithPoiUserApiTest.java index 11d573d3..c5374265 100644 --- a/xyz.hotchpotch.hogandiff/src/test/java/xyz/hotchpotch/hogandiff/logic/poi/SheetNamesLoaderWithPoiUserApiTest.java +++ b/xyz.hotchpotch.hogandiff/src/test/java/xyz/hotchpotch/hogandiff/logic/poi/BookInfoLoaderWithPoiUserApiTest.java @@ -13,10 +13,10 @@ import xyz.hotchpotch.hogandiff.logic.BookInfo; import xyz.hotchpotch.hogandiff.logic.ExcelHandlingException; -import xyz.hotchpotch.hogandiff.logic.SheetNamesLoader; +import xyz.hotchpotch.hogandiff.logic.BookInfoLoader; import xyz.hotchpotch.hogandiff.logic.SheetType; -class SheetNamesLoaderWithPoiUserApiTest { +class BookInfoLoaderWithPoiUserApiTest { // [static members] ******************************************************** @@ -36,7 +36,7 @@ class SheetNamesLoaderWithPoiUserApiTest { private static Path bookPwTest4_xls; private static Path bookPwTest4_xlsx; - private static Class me = SheetNamesLoaderWithPoiUserApiTest.class; + private static Class me = BookInfoLoaderWithPoiUserApiTest.class; @BeforeAll static void beforeAll() throws URISyntaxException { @@ -64,20 +64,20 @@ void testOf() { // 異常系 assertThrows( NullPointerException.class, - () -> SheetNamesLoaderWithPoiUserApi.of(null)); + () -> BookInfoLoaderWithPoiUserApi.of(null)); assertThrows( IllegalArgumentException.class, - () -> SheetNamesLoaderWithPoiUserApi.of(Set.of())); + () -> BookInfoLoaderWithPoiUserApi.of(Set.of())); // 正常系 assertTrue( - SheetNamesLoaderWithPoiUserApi.of( - EnumSet.allOf(SheetType.class)) instanceof SheetNamesLoaderWithPoiUserApi); + BookInfoLoaderWithPoiUserApi.of( + EnumSet.allOf(SheetType.class)) instanceof BookInfoLoaderWithPoiUserApi); } @Test void testLoadSheetNames_例外系_非チェック例外() { - SheetNamesLoader testee = SheetNamesLoaderWithPoiUserApi.of(Set.of(SheetType.WORKSHEET)); + BookInfoLoader testee = BookInfoLoaderWithPoiUserApi.of(Set.of(SheetType.WORKSHEET)); // null パラメータ assertThrows( @@ -92,7 +92,7 @@ void testOf() { @Test void testLoadSheetNames_例外系_チェック例外() { - SheetNamesLoader testee = SheetNamesLoaderWithPoiUserApi.of(Set.of(SheetType.WORKSHEET)); + BookInfoLoader testee = BookInfoLoaderWithPoiUserApi.of(Set.of(SheetType.WORKSHEET)); // 存在しないファイル assertEquals( @@ -110,7 +110,7 @@ void testOf() { @Test void testLoadSheetNames_全てのシート種別が対象の場合() throws ExcelHandlingException { - SheetNamesLoader testee = SheetNamesLoaderWithPoiUserApi.of(EnumSet.allOf(SheetType.class)); + BookInfoLoader testee = BookInfoLoaderWithPoiUserApi.of(EnumSet.allOf(SheetType.class)); assertEquals( BookInfo.ofLoadCompleted( @@ -142,7 +142,7 @@ void testOf() { @Test void testLoadSheetNames_ワークシートのみが対象の場合() throws ExcelHandlingException { - SheetNamesLoader testee = SheetNamesLoaderWithPoiUserApi.of(EnumSet.of(SheetType.WORKSHEET)); + BookInfoLoader testee = BookInfoLoaderWithPoiUserApi.of(EnumSet.of(SheetType.WORKSHEET)); // FIXME: [No.01 シート識別不正 - usermodel] .xls 形式の場合はシート種別を見分けられない。 // どうしようもないのかしら?? @@ -172,7 +172,7 @@ void testOf() { @Test void testLoadSheetNames_グラフシートのみが対象の場合() throws ExcelHandlingException { - SheetNamesLoader testee = SheetNamesLoaderWithPoiUserApi.of(EnumSet.of(SheetType.CHART_SHEET)); + BookInfoLoader testee = BookInfoLoaderWithPoiUserApi.of(EnumSet.of(SheetType.CHART_SHEET)); // FIXME: [No.01 シート識別不正 - usermodel] .xls 形式の場合はシート種別を見分けられない。 // どうしようもないのかしら?? @@ -200,7 +200,7 @@ void testOf() { @Test void testLoadSheetNames_ダイアログシートのみが対象の場合() throws ExcelHandlingException { - SheetNamesLoader testee = SheetNamesLoaderWithPoiUserApi.of(EnumSet.of(SheetType.DIALOG_SHEET)); + BookInfoLoader testee = BookInfoLoaderWithPoiUserApi.of(EnumSet.of(SheetType.DIALOG_SHEET)); // FIXME: [No.01 シート識別不正 - usermodel] .xls 形式の場合はシート種別を見分けられない。 // どうしようもないのかしら?? @@ -230,7 +230,7 @@ void testOf() { @Test void testLoadSheetNames_マクロシートのみが対象の場合() throws ExcelHandlingException { - SheetNamesLoader testee = SheetNamesLoaderWithPoiUserApi.of(EnumSet.of(SheetType.MACRO_SHEET)); + BookInfoLoader testee = BookInfoLoaderWithPoiUserApi.of(EnumSet.of(SheetType.MACRO_SHEET)); // FIXME: [No.01 シート識別不正 - usermodel] .xls 形式の場合はシート種別を見分けられない。 // どうしようもないのかしら?? @@ -266,7 +266,7 @@ void testOf() { @Test void testLoadSheetNames_読み取りPW指定なしの場合() { - SheetNamesLoader testee = SheetNamesLoaderWithPoiUserApi.of(EnumSet.allOf(SheetType.class)); + BookInfoLoader testee = BookInfoLoaderWithPoiUserApi.of(EnumSet.allOf(SheetType.class)); // 開ける assertDoesNotThrow( @@ -299,7 +299,7 @@ void testOf() { @Test void testLoadSheetNames_読み取りPW指定ありの場合() { - SheetNamesLoader testee = SheetNamesLoaderWithPoiUserApi.of(EnumSet.allOf(SheetType.class)); + BookInfoLoader testee = BookInfoLoaderWithPoiUserApi.of(EnumSet.allOf(SheetType.class)); assertDoesNotThrow( () -> testee.loadBookInfo(bookPwTest1_xls, "123")); @@ -335,7 +335,7 @@ void testOf() { @Test void testLoadSheetNames_誤った読み取りPW指定ありの場合() { - SheetNamesLoader testee = SheetNamesLoaderWithPoiUserApi.of(EnumSet.allOf(SheetType.class)); + BookInfoLoader testee = BookInfoLoaderWithPoiUserApi.of(EnumSet.allOf(SheetType.class)); assertDoesNotThrow( () -> testee.loadBookInfo(bookPwTest1_xls, "456")); diff --git a/xyz.hotchpotch.hogandiff/src/test/java/xyz/hotchpotch/hogandiff/logic/poi/PoiUtilTest1_possibleTypes.java b/xyz.hotchpotch.hogandiff/src/test/java/xyz/hotchpotch/hogandiff/logic/poi/PoiUtilTest1_possibleTypes.java index ec024371..22a4dddf 100644 --- a/xyz.hotchpotch.hogandiff/src/test/java/xyz/hotchpotch/hogandiff/logic/poi/PoiUtilTest1_possibleTypes.java +++ b/xyz.hotchpotch.hogandiff/src/test/java/xyz/hotchpotch/hogandiff/logic/poi/PoiUtilTest1_possibleTypes.java @@ -97,8 +97,7 @@ static void afterAll() throws IOException { EnumSet.of(SheetType.CHART_SHEET), PoiUtil.possibleTypes(test1_xlsm_A2_ChartSheet)); - // FIXME: [No.01 シート識別不正 - usermodel] どういう訳か .xlsm - // 形式のExcelブックから「3_ダイアログ」を読み込めない。 + // FIXME: [No.01 シート識別不正 - usermodel] どういう訳か .xlsm 形式のExcelブックから「3_ダイアログ」を読み込めない。 // つまり test1_xlsm_A3_DialogSheet == null。なのでテストできない。 // どうしようもないのかしら?? // assertEquals( diff --git a/xyz.hotchpotch.hogandiff/src/test/java/xyz/hotchpotch/hogandiff/logic/sax/SheetNamesLoaderWithSaxTest.java b/xyz.hotchpotch.hogandiff/src/test/java/xyz/hotchpotch/hogandiff/logic/sax/BookInfoLoaderWithSaxTest.java similarity index 78% rename from xyz.hotchpotch.hogandiff/src/test/java/xyz/hotchpotch/hogandiff/logic/sax/SheetNamesLoaderWithSaxTest.java rename to xyz.hotchpotch.hogandiff/src/test/java/xyz/hotchpotch/hogandiff/logic/sax/BookInfoLoaderWithSaxTest.java index c629ffd7..66657b01 100644 --- a/xyz.hotchpotch.hogandiff/src/test/java/xyz/hotchpotch/hogandiff/logic/sax/SheetNamesLoaderWithSaxTest.java +++ b/xyz.hotchpotch.hogandiff/src/test/java/xyz/hotchpotch/hogandiff/logic/sax/BookInfoLoaderWithSaxTest.java @@ -13,10 +13,10 @@ import xyz.hotchpotch.hogandiff.logic.BookInfo; import xyz.hotchpotch.hogandiff.logic.ExcelHandlingException; -import xyz.hotchpotch.hogandiff.logic.SheetNamesLoader; +import xyz.hotchpotch.hogandiff.logic.BookInfoLoader; import xyz.hotchpotch.hogandiff.logic.SheetType; -class SheetNamesLoaderWithSaxTest { +class BookInfoLoaderWithSaxTest { // [static members] ******************************************************** @@ -29,12 +29,12 @@ class SheetNamesLoaderWithSaxTest { @BeforeAll static void beforeAll() throws URISyntaxException { - test1_xls = Path.of(SheetNamesLoaderWithSaxTest.class.getResource("Test1.xls").toURI()); - test1_xlsb = Path.of(SheetNamesLoaderWithSaxTest.class.getResource("Test1.xlsb").toURI()); - test1_xlsm = Path.of(SheetNamesLoaderWithSaxTest.class.getResource("Test1.xlsm").toURI()); - test1_xlsx = Path.of(SheetNamesLoaderWithSaxTest.class.getResource("Test1.xlsx").toURI()); - test2_xls = Path.of(SheetNamesLoaderWithSaxTest.class.getResource("Test2_passwordAAA.xls").toURI()); - test2_xlsx = Path.of(SheetNamesLoaderWithSaxTest.class.getResource("Test2_passwordAAA.xlsx").toURI()); + test1_xls = Path.of(BookInfoLoaderWithSaxTest.class.getResource("Test1.xls").toURI()); + test1_xlsb = Path.of(BookInfoLoaderWithSaxTest.class.getResource("Test1.xlsb").toURI()); + test1_xlsm = Path.of(BookInfoLoaderWithSaxTest.class.getResource("Test1.xlsm").toURI()); + test1_xlsx = Path.of(BookInfoLoaderWithSaxTest.class.getResource("Test1.xlsx").toURI()); + test2_xls = Path.of(BookInfoLoaderWithSaxTest.class.getResource("Test2_passwordAAA.xls").toURI()); + test2_xlsx = Path.of(BookInfoLoaderWithSaxTest.class.getResource("Test2_passwordAAA.xlsx").toURI()); } // [instance members] ****************************************************** @@ -44,20 +44,20 @@ void testOf() { // 異常系 assertThrows( NullPointerException.class, - () -> SheetNamesLoaderWithSax.of(null)); + () -> BookInfoLoaderWithSax.of(null)); assertThrows( IllegalArgumentException.class, - () -> SheetNamesLoaderWithSax.of(Set.of())); + () -> BookInfoLoaderWithSax.of(Set.of())); // 正常系 assertTrue( - SheetNamesLoaderWithSax.of( - EnumSet.allOf(SheetType.class)) instanceof SheetNamesLoaderWithSax); + BookInfoLoaderWithSax.of( + EnumSet.allOf(SheetType.class)) instanceof BookInfoLoaderWithSax); } @Test void testLoadSheetNames_例外系_非チェック例外() { - SheetNamesLoader testee = SheetNamesLoaderWithSax.of(Set.of(SheetType.WORKSHEET)); + BookInfoLoader testee = BookInfoLoaderWithSax.of(Set.of(SheetType.WORKSHEET)); // null パラメータ assertThrows( @@ -78,7 +78,7 @@ void testOf() { @Test void testLoadSheetNames_例外系_チェック例外() { - SheetNamesLoader testee = SheetNamesLoaderWithSax.of(Set.of(SheetType.WORKSHEET)); + BookInfoLoader testee = BookInfoLoaderWithSax.of(Set.of(SheetType.WORKSHEET)); // 存在しないファイル assertEquals( @@ -93,7 +93,7 @@ void testOf() { @Test void testLoadSheetNames_全てのシート種別が対象の場合() throws ExcelHandlingException { - SheetNamesLoader testee = SheetNamesLoaderWithSax.of(EnumSet.allOf(SheetType.class)); + BookInfoLoader testee = BookInfoLoaderWithSax.of(EnumSet.allOf(SheetType.class)); assertEquals( BookInfo.ofLoadCompleted( @@ -111,7 +111,7 @@ void testOf() { @Test void testLoadSheetNames_ワークシートのみが対象の場合() throws ExcelHandlingException { - SheetNamesLoader testee = SheetNamesLoaderWithSax.of(EnumSet.of(SheetType.WORKSHEET)); + BookInfoLoader testee = BookInfoLoaderWithSax.of(EnumSet.of(SheetType.WORKSHEET)); // マクロ無しのブックのため「x4_マクロ」が通常のワークシートとして保存されたためか、 // 「x4_マクロ」も取得されている。 @@ -131,7 +131,7 @@ void testOf() { @Test void testLoadSheetNames_グラフシートのみが対象の場合() throws ExcelHandlingException { - SheetNamesLoader testee = SheetNamesLoaderWithSax.of(EnumSet.of(SheetType.CHART_SHEET)); + BookInfoLoader testee = BookInfoLoaderWithSax.of(EnumSet.of(SheetType.CHART_SHEET)); assertEquals( BookInfo.ofLoadCompleted( @@ -149,7 +149,7 @@ void testOf() { @Test void testLoadSheetNames_ダイアログシートのみが対象の場合() throws ExcelHandlingException { - SheetNamesLoader testee = SheetNamesLoaderWithSax.of(EnumSet.of(SheetType.DIALOG_SHEET)); + BookInfoLoader testee = BookInfoLoaderWithSax.of(EnumSet.of(SheetType.DIALOG_SHEET)); assertEquals( BookInfo.ofLoadCompleted( @@ -167,7 +167,7 @@ void testOf() { @Test void testLoadSheetNames_マクロシートのみが対象の場合() throws ExcelHandlingException { - SheetNamesLoader testee = SheetNamesLoaderWithSax.of(EnumSet.of(SheetType.MACRO_SHEET)); + BookInfoLoader testee = BookInfoLoaderWithSax.of(EnumSet.of(SheetType.MACRO_SHEET)); // マクロ無しのブックのため「x4_マクロ」が通常のワークシートとして保存されたためか、 // 「x4_マクロ」が取得されない。 diff --git a/xyz.hotchpotch.hogandiff/src/test/java/xyz/hotchpotch/hogandiff/util/function/UnsafeConsumerTest.java b/xyz.hotchpotch.hogandiff/src/test/java/xyz/hotchpotch/hogandiff/util/function/UnsafeConsumerTest.java index d5714b0b..3b0bafed 100644 --- a/xyz.hotchpotch.hogandiff/src/test/java/xyz/hotchpotch/hogandiff/util/function/UnsafeConsumerTest.java +++ b/xyz.hotchpotch.hogandiff/src/test/java/xyz/hotchpotch/hogandiff/util/function/UnsafeConsumerTest.java @@ -11,12 +11,12 @@ class UnsafeConsumerTest { // [static members] ******************************************************** - private static final UnsafeConsumer unsafe1 = x -> { + private static final UnsafeConsumer unsafe1 = _ -> { }; - private static final UnsafeConsumer unsafe2 = x -> { + private static final UnsafeConsumer unsafe2 = _ -> { throw new IOException("unsafe2"); }; - private static final UnsafeConsumer unsafe3 = x -> { + private static final UnsafeConsumer unsafe3 = _ -> { throw new IllegalArgumentException("unsafe3"); }; @@ -29,7 +29,7 @@ void testFrom() { () -> UnsafeConsumer.from(null)); assertTrue( - UnsafeConsumer.from(x -> { + UnsafeConsumer.from(_ -> { }) instanceof UnsafeConsumer); } diff --git a/xyz.hotchpotch.hogandiff/src/test/java/xyz/hotchpotch/hogandiff/util/function/UnsafeFunctionTest.java b/xyz.hotchpotch.hogandiff/src/test/java/xyz/hotchpotch/hogandiff/util/function/UnsafeFunctionTest.java index 21a897e7..d0b7e08e 100644 --- a/xyz.hotchpotch.hogandiff/src/test/java/xyz/hotchpotch/hogandiff/util/function/UnsafeFunctionTest.java +++ b/xyz.hotchpotch.hogandiff/src/test/java/xyz/hotchpotch/hogandiff/util/function/UnsafeFunctionTest.java @@ -14,22 +14,22 @@ class UnsafeFunctionTest { private static final UnsafeFunction unsafe1_1 = String::length; private static final UnsafeFunction unsafe1_2 = "x"::repeat; - private static final UnsafeFunction unsafe2_1 = s -> { + private static final UnsafeFunction unsafe2_1 = _ -> { throw new IOException("unsafe2_1"); }; - private static final UnsafeFunction unsafe2_2 = i -> { + private static final UnsafeFunction unsafe2_2 = _ -> { throw new SAXException("unsafe2_2"); }; - private static final UnsafeFunction unsafe2_3 = i -> { + private static final UnsafeFunction unsafe2_3 = _ -> { throw new IllegalArgumentException("unsafe2_3"); }; private static final Function safe1_1 = String::length; private static final Function safe1_2 = "x"::repeat; - private static final Function safe2_1 = s -> { + private static final Function safe2_1 = _ -> { throw new IllegalArgumentException("safe2_1"); }; - private static final Function safe2_2 = i -> { + private static final Function safe2_2 = _ -> { throw new UnsupportedOperationException("unsafe2_2"); }; @@ -56,7 +56,7 @@ void testFrom() { () -> UnsafeFunction.from(null)); assertTrue( - UnsafeFunction.from(x -> "Hello!!") instanceof UnsafeFunction); + UnsafeFunction.from(_ -> "Hello!!") instanceof UnsafeFunction); } @Test