From db86b8dd595acd34c242bea4a15ebbf0bf0fd45f Mon Sep 17 00:00:00 2001 From: a2geek Date: Wed, 16 Sep 2026 14:57:16 -0500 Subject: [PATCH] Split Sources into one targeted to FormattedDisk (com.webcodepro.applecommander.storage) and one targeted to FileStore (org.applecommander.source). --- .../webcodepro/applecommander/ui/AntTask.java | 2 +- .../com/webcodepro/applecommander/ui/ac.java | 2 +- .../applecommander/util/AppleSingleTest.java | 2 +- .../acx/command/ConvertCommand.java | 2 +- .../acx/command/CreateDiskCommand.java | 2 +- .../acx/command/ScanCommand.java | 2 +- .../acx/converter/DiskConverter.java | 2 +- .../DiskFactoryContextConverter.java | 2 +- .../applecommander/storage/Sources.java | 80 +++++++++++++++++++ .../applecommander/ui/DirectoryLister.java | 2 +- .../util/filestreamer/FileStreamer.java | 2 +- .../org/applecommander/source/Source.java | 8 +- .../org/applecommander/source/Sources.java | 5 ++ .../storage/DiskFileStoreTest.java | 1 - .../storage/DiskHelperTest.java | 1 - .../util/filestreamer/FileTupleTest.java | 2 +- .../ui/swt/DiskExplorerTab.java | 2 +- .../ui/swt/SwtAppleCommander.java | 2 +- .../comparedisks/CompareDisksResultsPane.java | 2 +- 19 files changed, 103 insertions(+), 20 deletions(-) create mode 100644 lib/ac-api/src/main/java/com/webcodepro/applecommander/storage/Sources.java diff --git a/app/ant-ac/src/main/java/com/webcodepro/applecommander/ui/AntTask.java b/app/ant-ac/src/main/java/com/webcodepro/applecommander/ui/AntTask.java index ee74cb3c..ccaab934 100644 --- a/app/ant-ac/src/main/java/com/webcodepro/applecommander/ui/AntTask.java +++ b/app/ant-ac/src/main/java/com/webcodepro/applecommander/ui/AntTask.java @@ -34,7 +34,7 @@ import org.apache.tools.ant.Task; import org.applecommander.image.DiskCopyImage; import org.applecommander.image.UniversalDiskImage; import org.applecommander.source.FileSource; -import org.applecommander.source.Sources; +import com.webcodepro.applecommander.storage.Sources; import java.io.FileInputStream; import java.io.FileOutputStream; diff --git a/app/cli-ac/src/main/java/com/webcodepro/applecommander/ui/ac.java b/app/cli-ac/src/main/java/com/webcodepro/applecommander/ui/ac.java index 0c128934..addc1266 100644 --- a/app/cli-ac/src/main/java/com/webcodepro/applecommander/ui/ac.java +++ b/app/cli-ac/src/main/java/com/webcodepro/applecommander/ui/ac.java @@ -49,7 +49,7 @@ import org.applecommander.hint.Hint; import org.applecommander.source.DataBufferSource; import org.applecommander.source.FileSource; import org.applecommander.source.Source; -import org.applecommander.source.Sources; +import com.webcodepro.applecommander.storage.Sources; import org.applecommander.util.BackupStrategy; import org.applecommander.util.Information; diff --git a/app/cli-ac/src/test/java/com/webcodepro/applecommander/util/AppleSingleTest.java b/app/cli-ac/src/test/java/com/webcodepro/applecommander/util/AppleSingleTest.java index e0d360da..db5ae4b4 100644 --- a/app/cli-ac/src/test/java/com/webcodepro/applecommander/util/AppleSingleTest.java +++ b/app/cli-ac/src/test/java/com/webcodepro/applecommander/util/AppleSingleTest.java @@ -23,7 +23,7 @@ import com.webcodepro.applecommander.storage.*; import com.webcodepro.applecommander.storage.os.prodos.ProdosFileEntry; import com.webcodepro.applecommander.ui.ac; import org.applecommander.source.Source; -import org.applecommander.source.Sources; +import com.webcodepro.applecommander.storage.Sources; import org.junit.jupiter.api.Test; import java.io.File; diff --git a/app/cli-acx/src/main/java/io/github/applecommander/acx/command/ConvertCommand.java b/app/cli-acx/src/main/java/io/github/applecommander/acx/command/ConvertCommand.java index 0265f74c..3cbae510 100644 --- a/app/cli-acx/src/main/java/io/github/applecommander/acx/command/ConvertCommand.java +++ b/app/cli-acx/src/main/java/io/github/applecommander/acx/command/ConvertCommand.java @@ -24,7 +24,7 @@ import com.webcodepro.applecommander.storage.Disks; import com.webcodepro.applecommander.storage.FormattedDisk; import io.github.applecommander.acx.base.ReusableCommandOptions; import org.applecommander.source.Source; -import org.applecommander.source.Sources; +import com.webcodepro.applecommander.storage.Sources; import org.applecommander.util.BackupStrategy; import picocli.CommandLine.Command; import picocli.CommandLine.Option; diff --git a/app/cli-acx/src/main/java/io/github/applecommander/acx/command/CreateDiskCommand.java b/app/cli-acx/src/main/java/io/github/applecommander/acx/command/CreateDiskCommand.java index b3bc80b1..6a7df188 100644 --- a/app/cli-acx/src/main/java/io/github/applecommander/acx/command/CreateDiskCommand.java +++ b/app/cli-acx/src/main/java/io/github/applecommander/acx/command/CreateDiskCommand.java @@ -36,7 +36,7 @@ import org.applecommander.os.dos.OzdosAdapterStrategy; import org.applecommander.os.dos.UnidosAdapterStrategy; import org.applecommander.source.DataBufferSource; import org.applecommander.source.Source; -import org.applecommander.source.Sources; +import com.webcodepro.applecommander.storage.Sources; import org.applecommander.util.BackupStrategy; import picocli.CommandLine.ArgGroup; import picocli.CommandLine.Command; diff --git a/app/cli-acx/src/main/java/io/github/applecommander/acx/command/ScanCommand.java b/app/cli-acx/src/main/java/io/github/applecommander/acx/command/ScanCommand.java index a0bc9a59..3e8ab15b 100644 --- a/app/cli-acx/src/main/java/io/github/applecommander/acx/command/ScanCommand.java +++ b/app/cli-acx/src/main/java/io/github/applecommander/acx/command/ScanCommand.java @@ -34,7 +34,7 @@ import io.github.applecommander.acx.base.ReusableCommandOptions; import org.applecommander.device.BlockDevice; import org.applecommander.device.TrackSectorDevice; import org.applecommander.source.Source; -import org.applecommander.source.Sources; +import com.webcodepro.applecommander.storage.Sources; import java.io.FileReader; import java.io.IOException; diff --git a/app/cli-acx/src/main/java/io/github/applecommander/acx/converter/DiskConverter.java b/app/cli-acx/src/main/java/io/github/applecommander/acx/converter/DiskConverter.java index 059b9b18..ac5026ce 100644 --- a/app/cli-acx/src/main/java/io/github/applecommander/acx/converter/DiskConverter.java +++ b/app/cli-acx/src/main/java/io/github/applecommander/acx/converter/DiskConverter.java @@ -23,7 +23,7 @@ import com.webcodepro.applecommander.storage.DiskFactory; import com.webcodepro.applecommander.storage.Disks; import com.webcodepro.applecommander.storage.FormattedDisk; import org.applecommander.source.Source; -import org.applecommander.source.Sources; +import com.webcodepro.applecommander.storage.Sources; import picocli.CommandLine.ITypeConverter; import picocli.CommandLine.TypeConversionException; diff --git a/app/cli-acx/src/main/java/io/github/applecommander/acx/converter/DiskFactoryContextConverter.java b/app/cli-acx/src/main/java/io/github/applecommander/acx/converter/DiskFactoryContextConverter.java index e733533a..f81ee33e 100644 --- a/app/cli-acx/src/main/java/io/github/applecommander/acx/converter/DiskFactoryContextConverter.java +++ b/app/cli-acx/src/main/java/io/github/applecommander/acx/converter/DiskFactoryContextConverter.java @@ -22,7 +22,7 @@ package io.github.applecommander.acx.converter; import com.webcodepro.applecommander.storage.DiskFactory; import com.webcodepro.applecommander.storage.Disks; import org.applecommander.source.Source; -import org.applecommander.source.Sources; +import com.webcodepro.applecommander.storage.Sources; import picocli.CommandLine.ITypeConverter; import picocli.CommandLine.TypeConversionException; diff --git a/lib/ac-api/src/main/java/com/webcodepro/applecommander/storage/Sources.java b/lib/ac-api/src/main/java/com/webcodepro/applecommander/storage/Sources.java new file mode 100644 index 00000000..97bab0f7 --- /dev/null +++ b/lib/ac-api/src/main/java/com/webcodepro/applecommander/storage/Sources.java @@ -0,0 +1,80 @@ +/* + * AppleCommander - An Apple ][ image utility. + * Copyright (C) 2025 by Robert Greene and others + * robgreene at users.sourceforge.net + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +package com.webcodepro.applecommander.storage; + +import org.applecommander.source.Source; + +import java.util.*; + +/// Sources is a hook into the Source discovery and construction logic. +/// Note that this is the LEGACY Sources interface. It will unwrap a SHK/SDK into +/// a disk image instead of delivering a `ShrinkitFileStore`. Use the Sources class +/// in the `org.applecommander.source` package if making a `FileStore`. +public class Sources { + private static final List FACTORIES; + static { + FACTORIES = new ArrayList<>(); + for (Source.Factory factory : ServiceLoader.load(Source.Factory.class)) { + FACTORIES.add(factory); + } + } + + /** + * This call is a shim for the AntTask to populate its known factories since ServiceLoader + * doesn't appear to work within the Ant classpath. + */ + public static void setFactories(Source.Factory... factories) { + FACTORIES.clear(); + FACTORIES.addAll(Arrays.asList(factories)); + } + + /** + * Standardized Source creation. Uses the ServiceLoader mechanism to identify + * all potential Source factories. Note that this supports a Source being + * passed as well (which ensures any wrapping layers are added, such as 2IMG + * or DiskCopy). + */ + public static Optional create(Object object) { + // First: Create source from a generalized object (thus, can be Path, Entry, URL, etc) + Optional source = Optional.empty(); + if (object instanceof Source objSource) { + source = Optional.of(objSource); + } + else { + for (Source.Factory factory : FACTORIES) { + source = factory.fromObject(object); + if (source.isPresent()) { + break; + } + } + } + // Second: Once we have a source, run a pass again, checking if there is a wrapper we need (2IMG, DiskCopy, etc) + if (source.isPresent()) { + for (Source.Factory factory : FACTORIES) { + Optional fromSource = factory.fromSource(source.get()); + if (fromSource.isPresent()) { + return fromSource; + } + } + } + return source; + } + +} diff --git a/lib/ac-api/src/main/java/com/webcodepro/applecommander/ui/DirectoryLister.java b/lib/ac-api/src/main/java/com/webcodepro/applecommander/ui/DirectoryLister.java index 9d183952..68592c74 100644 --- a/lib/ac-api/src/main/java/com/webcodepro/applecommander/ui/DirectoryLister.java +++ b/lib/ac-api/src/main/java/com/webcodepro/applecommander/ui/DirectoryLister.java @@ -35,7 +35,7 @@ import org.apache.commons.csv.CSVPrinter; import org.applecommander.device.BlockDevice; import org.applecommander.device.TrackSectorDevice; import org.applecommander.source.Source; -import org.applecommander.source.Sources; +import com.webcodepro.applecommander.storage.Sources; import java.io.IOException; import java.io.UncheckedIOException; diff --git a/lib/ac-api/src/main/java/com/webcodepro/applecommander/util/filestreamer/FileStreamer.java b/lib/ac-api/src/main/java/com/webcodepro/applecommander/util/filestreamer/FileStreamer.java index f06168cc..667a028c 100644 --- a/lib/ac-api/src/main/java/com/webcodepro/applecommander/util/filestreamer/FileStreamer.java +++ b/lib/ac-api/src/main/java/com/webcodepro/applecommander/util/filestreamer/FileStreamer.java @@ -22,7 +22,7 @@ package com.webcodepro.applecommander.util.filestreamer; import com.webcodepro.applecommander.storage.*; import com.webcodepro.applecommander.util.GlobGenerator; import org.applecommander.source.Source; -import org.applecommander.source.Sources; +import com.webcodepro.applecommander.storage.Sources; import java.io.File; import java.io.IOException; diff --git a/lib/ac-api/src/main/java/org/applecommander/source/Source.java b/lib/ac-api/src/main/java/org/applecommander/source/Source.java index a369fc0a..6b086c4f 100644 --- a/lib/ac-api/src/main/java/org/applecommander/source/Source.java +++ b/lib/ac-api/src/main/java/org/applecommander/source/Source.java @@ -32,15 +32,15 @@ import java.util.Optional; * Source and Factory for an archive or disk in AppleCommander. *

* Typical usage: - * {@snippet lang=java: - * Optional sourceOpt = Sources.create(Path.of(filename)); + * {@snippet lang = java: + * import com.webcodepro.applecommander.storage.Sources;Optional sourceOpt = Sources.create(Path.of(filename)); * if (sourceOpt.isPresent()) { * // do something with sourceOpt.get() * System.out.println(sourceOpt.get().getSize()); - * } + * } * // Only happens if the initiating object is not understood * throw new RuntimeException("Unable to create image source"); - * } + *} */ public interface Source extends CapabilityProvider, HintProvider, Container { int getSize(); diff --git a/lib/ac-api/src/main/java/org/applecommander/source/Sources.java b/lib/ac-api/src/main/java/org/applecommander/source/Sources.java index 7200d637..84e77d82 100644 --- a/lib/ac-api/src/main/java/org/applecommander/source/Sources.java +++ b/lib/ac-api/src/main/java/org/applecommander/source/Sources.java @@ -19,6 +19,8 @@ */ package org.applecommander.source; +import com.webcodepro.applecommander.storage.ShrinkitSourceFactory; + import java.util.*; /** @@ -29,6 +31,9 @@ public class Sources { static { FACTORIES = new ArrayList<>(); for (Source.Factory factory : ServiceLoader.load(Source.Factory.class)) { + if (factory instanceof ShrinkitSourceFactory) { + continue; + } FACTORIES.add(factory); } } diff --git a/lib/ac-api/src/test/java/com/webcodepro/applecommander/storage/DiskFileStoreTest.java b/lib/ac-api/src/test/java/com/webcodepro/applecommander/storage/DiskFileStoreTest.java index ffd70977..9f0964e8 100644 --- a/lib/ac-api/src/test/java/com/webcodepro/applecommander/storage/DiskFileStoreTest.java +++ b/lib/ac-api/src/test/java/com/webcodepro/applecommander/storage/DiskFileStoreTest.java @@ -24,7 +24,6 @@ import org.applecommander.filestore.FileEntry; import org.applecommander.filestore.FileStore; import org.applecommander.filestore.FileStoreTestHelper; import org.applecommander.source.Source; -import org.applecommander.source.Sources; import org.junit.jupiter.api.Test; import java.io.IOException; diff --git a/lib/ac-api/src/test/java/com/webcodepro/applecommander/storage/DiskHelperTest.java b/lib/ac-api/src/test/java/com/webcodepro/applecommander/storage/DiskHelperTest.java index e6594a46..ae0b0839 100644 --- a/lib/ac-api/src/test/java/com/webcodepro/applecommander/storage/DiskHelperTest.java +++ b/lib/ac-api/src/test/java/com/webcodepro/applecommander/storage/DiskHelperTest.java @@ -23,7 +23,6 @@ import com.webcodepro.applecommander.storage.FormattedDisk.DiskUsage; import com.webcodepro.applecommander.storage.filters.*; import com.webcodepro.applecommander.testconfig.TestConfig; import org.applecommander.source.Source; -import org.applecommander.source.Sources; import org.junit.jupiter.api.Test; import java.io.IOException; diff --git a/lib/ac-api/src/test/java/com/webcodepro/applecommander/util/filestreamer/FileTupleTest.java b/lib/ac-api/src/test/java/com/webcodepro/applecommander/util/filestreamer/FileTupleTest.java index 65568ecc..0d8d59b7 100644 --- a/lib/ac-api/src/test/java/com/webcodepro/applecommander/util/filestreamer/FileTupleTest.java +++ b/lib/ac-api/src/test/java/com/webcodepro/applecommander/util/filestreamer/FileTupleTest.java @@ -21,7 +21,7 @@ package com.webcodepro.applecommander.util.filestreamer; import com.webcodepro.applecommander.storage.*; import org.applecommander.source.Source; -import org.applecommander.source.Sources; +import com.webcodepro.applecommander.storage.Sources; import org.junit.jupiter.api.Test; import java.util.List; diff --git a/lib/ac-swt-common/src/main/java/com/webcodepro/applecommander/ui/swt/DiskExplorerTab.java b/lib/ac-swt-common/src/main/java/com/webcodepro/applecommander/ui/swt/DiskExplorerTab.java index 2a9e0f85..26636cb6 100644 --- a/lib/ac-swt-common/src/main/java/com/webcodepro/applecommander/ui/swt/DiskExplorerTab.java +++ b/lib/ac-swt-common/src/main/java/com/webcodepro/applecommander/ui/swt/DiskExplorerTab.java @@ -52,7 +52,7 @@ import org.applecommander.os.DiskCheck; import org.applecommander.os.DiskOptimizer; import org.applecommander.source.DataBufferSource; import org.applecommander.source.Source; -import org.applecommander.source.Sources; +import com.webcodepro.applecommander.storage.Sources; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.CTabFolder; import org.eclipse.swt.custom.CTabItem; diff --git a/lib/ac-swt-common/src/main/java/com/webcodepro/applecommander/ui/swt/SwtAppleCommander.java b/lib/ac-swt-common/src/main/java/com/webcodepro/applecommander/ui/swt/SwtAppleCommander.java index a2d01090..926efc85 100644 --- a/lib/ac-swt-common/src/main/java/com/webcodepro/applecommander/ui/swt/SwtAppleCommander.java +++ b/lib/ac-swt-common/src/main/java/com/webcodepro/applecommander/ui/swt/SwtAppleCommander.java @@ -33,7 +33,7 @@ import com.webcodepro.applecommander.ui.swt.wizard.diskimage.DiskImageWizard; import com.webcodepro.applecommander.util.Host; import com.webcodepro.applecommander.util.TextBundle; import org.applecommander.source.Source; -import org.applecommander.source.Sources; +import com.webcodepro.applecommander.storage.Sources; import org.eclipse.swt.SWT; import org.eclipse.swt.events.DisposeEvent; import org.eclipse.swt.events.SelectionAdapter; diff --git a/lib/ac-swt-common/src/main/java/com/webcodepro/applecommander/ui/swt/wizard/comparedisks/CompareDisksResultsPane.java b/lib/ac-swt-common/src/main/java/com/webcodepro/applecommander/ui/swt/wizard/comparedisks/CompareDisksResultsPane.java index 3ed33695..0bc27280 100644 --- a/lib/ac-swt-common/src/main/java/com/webcodepro/applecommander/ui/swt/wizard/comparedisks/CompareDisksResultsPane.java +++ b/lib/ac-swt-common/src/main/java/com/webcodepro/applecommander/ui/swt/wizard/comparedisks/CompareDisksResultsPane.java @@ -28,7 +28,7 @@ import com.webcodepro.applecommander.ui.UiBundle; import com.webcodepro.applecommander.ui.swt.wizard.WizardPane; import com.webcodepro.applecommander.util.TextBundle; import org.applecommander.source.Source; -import org.applecommander.source.Sources; +import com.webcodepro.applecommander.storage.Sources; import org.eclipse.swt.SWT; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout;