First round of moving away from Disk constructor to using Disks and/or Sources.

This commit is contained in:
Rob Greene
2025-08-23 11:41:21 -05:00
parent 95858e2041
commit f46b43ae67
11 changed files with 116 additions and 105 deletions
@@ -62,6 +62,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 org.applecommander.util.Information;
/**
@@ -215,10 +216,10 @@ public class ac {
if (!file.canRead()){
throw new IOException("Unable to read input file named "+imageName+".");
}
Disk disk = new Disk(imageName);
FormattedDisk[] formattedDisks = disk.getFormattedDisks();
FormattedDisk formattedDisk = formattedDisks[0];
Source source = Sources.create(file).orElseThrow();
DiskFactory.Context ctx = Disks.inspect(source);
FormattedDisk formattedDisk = ctx.disks.getFirst();
// Look through the supplied types and try to pick AppleSoft. Otherwise, let's try "A".
String fileType = Arrays.asList(formattedDisk.getFiletypes()).stream()
.filter(ft -> "A".equalsIgnoreCase(ft) || "BAS".equalsIgnoreCase(ft))
@@ -254,9 +255,9 @@ public class ac {
while ((byteCount = is.read(inb)) > 0) {
buf.write(inb, 0, byteCount);
}
Disk disk = new Disk(imageName);
FormattedDisk[] formattedDisks = disk.getFormattedDisks();
FormattedDisk formattedDisk = formattedDisks[0];
Source source = Sources.create(Path.of(imageName)).orElseThrow();
DiskFactory.Context ctx = Disks.inspect(source);
FormattedDisk formattedDisk = ctx.disks.getFirst();
FileEntry entry = name.createEntry(formattedDisk);
if (entry != null) {
entry.setFiletype(fileType);
@@ -307,12 +308,12 @@ public class ac {
ByteArrayOutputStream buf = new ByteArrayOutputStream();
StreamUtil.copy(inputStream, buf);
Disk disk = new Disk(imageName);
FormattedDisk[] formattedDisks = disk.getFormattedDisks();
if (formattedDisks == null)
Source source = Sources.create(Path.of(imageName)).orElseThrow();
DiskFactory.Context ctx = Disks.inspect(source);
if (ctx.disks.isEmpty())
System.out.println("Dude, formattedDisks is null!");
FormattedDisk formattedDisk = formattedDisks[0];
if (!disk.getSource().isAny(Hint.DISK_COPY_IMAGE, Hint.ORIGIN_SHRINKIT, Hint.UNIVERSAL_DISK_IMAGE)) {
FormattedDisk formattedDisk = ctx.disks.getFirst();
if (!source.isAny(Hint.DISK_COPY_IMAGE, Hint.ORIGIN_SHRINKIT, Hint.UNIVERSAL_DISK_IMAGE)) {
FileEntry entry = name.createEntry(formattedDisk);
if (entry != null) {
entry.setFiletype(fileType);
@@ -405,16 +406,16 @@ public class ac {
*/
static void deleteFile(String imageName, String fileName)
throws IOException, DiskException {
Disk disk = new Disk(imageName);
Source source = Sources.create(Path.of(imageName)).orElseThrow();
DiskFactory.Context ctx = Disks.inspect(source);
Name name = new Name(fileName);
if (!disk.getSource().isAny(Hint.DISK_COPY_IMAGE, Hint.ORIGIN_SHRINKIT, Hint.UNIVERSAL_DISK_IMAGE)) {
FormattedDisk[] formattedDisks = disk.getFormattedDisks();
for (int i = 0; i < formattedDisks.length; i++) {
FormattedDisk formattedDisk = formattedDisks[i];
if (!source.isAny(Hint.DISK_COPY_IMAGE, Hint.ORIGIN_SHRINKIT, Hint.UNIVERSAL_DISK_IMAGE)) {
for (int i = 0; i < ctx.disks.size(); i++) {
FormattedDisk formattedDisk = ctx.disks.get(i);
FileEntry entry = name.getEntry(formattedDisk);
if (entry != null) {
entry.delete();
disk.save();
formattedDisk.save();
} else {
System.err.println(textBundle.format(
"CommandLineNoMatchMessage", name.fullName)); //$NON-NLS-1$
@@ -431,13 +432,13 @@ public class ac {
*/
static void getFile(String imageName, String fileName, boolean filter, PrintStream out)
throws IOException, DiskException {
Disk disk = new Disk(imageName);
Source source = Sources.create(Path.of(imageName)).orElseThrow();
DiskFactory.Context ctx = Disks.inspect(source);
Name name = new Name(fileName);
FormattedDisk[] formattedDisks = disk.getFormattedDisks();
if (out == null)
out = System.out;
for (int i = 0; i < formattedDisks.length; i++) {
FormattedDisk formattedDisk = formattedDisks[i];
for (int i = 0; i < ctx.disks.size(); i++) {
FormattedDisk formattedDisk = ctx.disks.get(i);
FileEntry entry = name.getEntry(formattedDisk);
if (entry != null) {
if (filter) {
@@ -461,7 +462,8 @@ public class ac {
* Extract all files in the image according to their respective filetype.
*/
static void getFiles(String imageName, String directory) throws IOException, DiskException {
Disk disk = new Disk(imageName);
Source source = Sources.create(Path.of(imageName)).orElseThrow();
DiskFactory.Context ctx = Disks.inspect(source);
if ((directory != null) && (directory.length() > 0)) {
// Add a final directory separator if the user didn't supply one
if (!directory.endsWith(File.separator))
@@ -469,9 +471,8 @@ public class ac {
} else {
directory = "."+File.separator;
}
FormattedDisk[] formattedDisks = disk.getFormattedDisks();
for (int i = 0; i < formattedDisks.length; i++) {
FormattedDisk formattedDisk = formattedDisks[i];
for (int i = 0; i < ctx.disks.size(); i++) {
FormattedDisk formattedDisk = ctx.disks.get(i);
writeFiles(formattedDisk.getFiles(), directory);
}
}
@@ -544,18 +545,16 @@ public class ac {
*/
static void getDiskInfo(String[] args) throws IOException, DiskException {
for (int d = 1; d < args.length; d++) {
Disk disk = new Disk(args[d]);
FormattedDisk[] formattedDisks = disk.getFormattedDisks();
for (int i = 0; i < formattedDisks.length; i++) {
FormattedDisk formattedDisk = formattedDisks[i];
Source source = Sources.create(Path.of(args[d])).orElseThrow();
DiskFactory.Context ctx = Disks.inspect(source);
for (int i = 0; i < ctx.disks.size(); i++) {
FormattedDisk formattedDisk = ctx.disks.get(i);
for (DiskInformation diskinfo : formattedDisk.getDiskInformation()) {
System.out.println(diskinfo.getLabel() + ": " + diskinfo.getValue());
}
formattedDisk.getSource().get(Source.class).ifPresent(source -> {
for (Information info : source.information()) {
System.out.println(info.label() + ": " + info.value());
}
});
for (Information info : source.information()) {
System.out.println(info.label() + ": " + info.value());
}
}
System.out.println();
}
@@ -575,15 +574,15 @@ public class ac {
*/
static void setFileLocked(String imageName, Name name,
boolean lockState) throws IOException, DiskException {
Disk disk = new Disk(imageName);
if (!disk.getSource().isAny(Hint.DISK_COPY_IMAGE, Hint.ORIGIN_SHRINKIT, Hint.UNIVERSAL_DISK_IMAGE)) {
FormattedDisk[] formattedDisks = disk.getFormattedDisks();
for (int i = 0; i < formattedDisks.length; i++) {
FormattedDisk formattedDisk = formattedDisks[i];
Source source = Sources.create(Path.of(imageName)).orElseThrow();
DiskFactory.Context ctx = Disks.inspect(source);
if (!source.isAny(Hint.DISK_COPY_IMAGE, Hint.ORIGIN_SHRINKIT, Hint.UNIVERSAL_DISK_IMAGE)) {
for (int i = 0; i < ctx.disks.size(); i++) {
FormattedDisk formattedDisk = ctx.disks.get(i);
FileEntry entry = name.getEntry(formattedDisk);
if (entry != null) {
entry.setLocked(lockState);
disk.save();
formattedDisk.save();
} else {
System.err.println(textBundle.format(
"CommandLineNoMatchMessage", name.fullName)); //$NON-NLS-1$
@@ -600,12 +599,12 @@ public class ac {
*/
public static void setDiskName(String imageName, String volName)
throws IOException, DiskException {
Disk disk = new Disk(imageName);
if (!disk.getSource().isAny(Hint.DISK_COPY_IMAGE, Hint.ORIGIN_SHRINKIT, Hint.UNIVERSAL_DISK_IMAGE)) {
FormattedDisk[] formattedDisks = disk.getFormattedDisks();
FormattedDisk formattedDisk = formattedDisks[0];
Source source = Sources.create(Path.of(imageName)).orElseThrow();
DiskFactory.Context ctx = Disks.inspect(source);
if (!source.isAny(Hint.DISK_COPY_IMAGE, Hint.ORIGIN_SHRINKIT, Hint.UNIVERSAL_DISK_IMAGE)) {
FormattedDisk formattedDisk = ctx.disks.getFirst();
formattedDisk.setDiskName(volName);
formattedDisks[0].save();
formattedDisk.save();
}
else
throw new IOException(textBundle.get("CommandLineSDKReadOnly"));
@@ -21,14 +21,14 @@ package com.webcodepro.applecommander.util;
import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.util.List;
import com.webcodepro.applecommander.storage.Disk;
import com.webcodepro.applecommander.storage.DiskException;
import com.webcodepro.applecommander.storage.FileEntry;
import com.webcodepro.applecommander.storage.FormattedDisk;
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 org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
@@ -49,9 +49,10 @@ public class AppleSingleTest {
// Actually test the implementation!
ac.putAppleSingle(tmpImageName, "HELLO", getClass().getResourceAsStream(AS_HELLO_BIN));
Disk disk = new Disk(tmpImageName);
FormattedDisk formattedDisk = disk.getFormattedDisks()[0];
Source source = Sources.create(Path.of(tmpImageName)).orElseThrow();
DiskFactory.Context ctx = Disks.inspect(source);
FormattedDisk formattedDisk = ctx.disks.getFirst();
List<FileEntry> files = formattedDisk.getFiles();
assertNotNull(files);
assertEquals(1, files.size());
@@ -21,9 +21,12 @@ package io.github.applecommander.acx.command;
import java.io.File;
import com.webcodepro.applecommander.storage.Disk;
import com.webcodepro.applecommander.storage.DiskFactory;
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 picocli.CommandLine.Command;
import picocli.CommandLine.Option;
import picocli.CommandLine.Parameters;
@@ -48,11 +51,13 @@ public class ConvertCommand extends ReusableCommandOptions {
if (targetFile.exists() && !overwriteFlag) {
throw new RuntimeException("File exists and overwriting not enabled.");
}
Disk disk = new Disk(archiveName);
Source source = Sources.create(targetFile).orElseThrow();
DiskFactory.Context ctx = Disks.inspect(source);
FormattedDisk disk = ctx.disks.getFirst();
disk.setFilename(diskName);
saveDisk(disk);
return 0;
}
}
@@ -22,7 +22,8 @@ package io.github.applecommander.acx.command;
import java.util.Optional;
import java.util.logging.Logger;
import com.webcodepro.applecommander.storage.Disk;
import com.webcodepro.applecommander.storage.DiskFactory;
import com.webcodepro.applecommander.storage.Disks;
import com.webcodepro.applecommander.storage.FormattedDisk;
import com.webcodepro.applecommander.storage.os.dos33.DosFormatDisk;
import com.webcodepro.applecommander.storage.os.dos33.OzDosFormatDisk;
@@ -35,6 +36,8 @@ import io.github.applecommander.acx.OrderType;
import io.github.applecommander.acx.SystemType;
import io.github.applecommander.acx.base.ReusableCommandOptions;
import io.github.applecommander.acx.converter.DataSizeConverter;
import org.applecommander.source.Source;
import org.applecommander.source.Sources;
import picocli.CommandLine.ArgGroup;
import picocli.CommandLine.Command;
import picocli.CommandLine.Option;
@@ -100,8 +103,9 @@ public class CreateDiskCommand extends ReusableCommandOptions {
}
if (formatSource != null) {
Disk systemSource = new Disk(formatSource);
systemType.copySystem(disks[0], systemSource.getFormattedDisks()[0]);
Source source = Sources.create(formatSource).orElseThrow();
DiskFactory.Context ctx = Disks.inspect(source);
systemType.copySystem(disks[0], ctx.disks.getFirst());
}
saveDisk(disks[0]);
@@ -22,11 +22,8 @@ package io.github.applecommander.acx.command;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonStreamParser;
import com.webcodepro.applecommander.storage.DirectoryEntry;
import com.webcodepro.applecommander.storage.Disk;
import com.webcodepro.applecommander.storage.FileEntry;
import com.webcodepro.applecommander.storage.*;
import com.webcodepro.applecommander.storage.FilenameFilter;
import com.webcodepro.applecommander.storage.FormattedDisk;
import com.webcodepro.applecommander.storage.os.cpm.CpmFormatDisk;
import com.webcodepro.applecommander.storage.os.dos33.DosFormatDisk;
import com.webcodepro.applecommander.storage.os.gutenberg.GutenbergFormatDisk;
@@ -35,6 +32,8 @@ import com.webcodepro.applecommander.storage.os.pascal.PascalFormatDisk;
import com.webcodepro.applecommander.storage.os.prodos.ProdosFormatDisk;
import com.webcodepro.applecommander.storage.os.rdos.RdosFormatDisk;
import io.github.applecommander.acx.base.ReusableCommandOptions;
import org.applecommander.source.Source;
import org.applecommander.source.Sources;
import java.io.*;
import java.nio.file.*;
@@ -350,8 +349,9 @@ public class ScanCommand extends ReusableCommandOptions {
Report(Path file) {
try {
imageName = file.toString();
Disk disk = new Disk(file.toString());
for (FormattedDisk fdisk : disk.getFormattedDisks()) {
Source source = Sources.create(imageName).orElseThrow();
DiskFactory.Context ctx = Disks.inspect(source);
for (FormattedDisk fdisk : ctx.disks) {
logicalDisks++;
imageType = fdisk.getFormat();
readAllFiles(fdisk);
@@ -24,15 +24,13 @@ import java.io.UncheckedIOException;
import java.util.List;
import java.util.stream.Collectors;
import com.webcodepro.applecommander.storage.*;
import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVPrinter;
import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.webcodepro.applecommander.storage.Disk;
import com.webcodepro.applecommander.storage.DiskUnrecognizedException;
import com.webcodepro.applecommander.storage.FormattedDisk;
import com.webcodepro.applecommander.storage.FormattedDisk.FileColumnHeader;
import com.webcodepro.applecommander.util.TextBundle;
import com.webcodepro.applecommander.util.filestreamer.FileStreamer;
@@ -38,11 +38,9 @@ import java.util.function.Predicate;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
import com.webcodepro.applecommander.storage.Disk;
import com.webcodepro.applecommander.storage.DiskException;
import com.webcodepro.applecommander.storage.DiskUnrecognizedException;
import com.webcodepro.applecommander.storage.FileEntry;
import com.webcodepro.applecommander.storage.FormattedDisk;
import com.webcodepro.applecommander.storage.*;
import org.applecommander.source.Source;
import org.applecommander.source.Sources;
/**
* FileStreamer is utility class that will (optionally) recurse through all directories and
@@ -67,7 +65,9 @@ public class FileStreamer {
return forDisk(file.getPath());
}
public static FileStreamer forDisk(String fileName) throws IOException, DiskUnrecognizedException {
return new FileStreamer(new Disk(fileName));
Source source = Sources.create(fileName).orElseThrow();
DiskFactory.Context ctx = Disks.inspect(source);
return new FileStreamer(ctx.disks.toArray(new FormattedDisk[0]));
}
public static FileStreamer forDisk(Disk disk) throws DiskUnrecognizedException {
return new FileStreamer(disk);
@@ -25,10 +25,7 @@ import org.applecommander.util.Container;
import org.applecommander.util.DataBuffer;
import org.applecommander.util.Information;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
@@ -127,10 +124,12 @@ public class FileSource implements Source {
public static class Factory implements Source.Factory {
@Override
public Optional<Source> fromObject(Object object) {
if (object instanceof Path path) {
return Optional.of(new FileSource(path));
}
return Optional.empty();
return switch(object) {
case Path path -> Optional.of(new FileSource(path));
case File file -> Optional.of(new FileSource(file.toPath()));
case String filename -> Optional.of(new FileSource(Path.of(filename)));
default -> Optional.empty();
};
}
@Override
@@ -22,6 +22,8 @@ package com.webcodepro.applecommander.storage;
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;
@@ -219,10 +221,10 @@ public class DiskHelperTest {
}
protected FormattedDisk[] showDirectory(String imageName) throws IOException, DiskException {
Disk disk = new Disk(imageName);
FormattedDisk[] formattedDisks = disk.getFormattedDisks();
for (int i=0; i<formattedDisks.length; i++) {
FormattedDisk formattedDisk = formattedDisks[i];
Source source = Sources.create(imageName).orElseThrow();
DiskFactory.Context ctx = Disks.inspect(source);
for (int i=0; i<ctx.disks.size(); i++) {
FormattedDisk formattedDisk = ctx.disks.get(i);
System.out.println();
System.out.println(formattedDisk.getDiskName());
List<FileEntry> files = formattedDisk.getFiles();
@@ -238,7 +240,7 @@ public class DiskHelperTest {
showDiskUsage(formattedDisk);
}
return formattedDisks;
return ctx.disks.toArray(new FormattedDisk[0]);
}
protected void showFiles(List<FileEntry> files, String indent) throws DiskException {
@@ -22,10 +22,9 @@ package com.webcodepro.applecommander.util.filestreamer;
import java.io.IOException;
import java.util.List;
import com.webcodepro.applecommander.storage.Disk;
import com.webcodepro.applecommander.storage.DiskException;
import com.webcodepro.applecommander.storage.FileEntry;
import com.webcodepro.applecommander.storage.FormattedDisk;
import com.webcodepro.applecommander.storage.*;
import org.applecommander.source.Source;
import org.applecommander.source.Sources;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
@@ -33,8 +32,9 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
public class FileTupleTest {
@Test
public void test() throws IOException, DiskException {
Disk disk = new Disk("./src/test/resources/disks/MERLIN8PRO1.DSK");
FormattedDisk formattedDisk = disk.getFormattedDisks()[0];
Source source = Sources.create("./src/test/resources/disks/MERLIN8PRO1.DSK").orElseThrow();
DiskFactory.Context ctx = Disks.inspect(source);
FormattedDisk formattedDisk = ctx.disks.getFirst();
FileTuple tuple = FileTuple.of(formattedDisk);
FileEntry sourcerorDir = tuple.formattedDisk.getFile("SOURCEROR");
tuple = tuple.pushd(sourcerorDir);
@@ -19,10 +19,7 @@
*/
package com.webcodepro.applecommander.ui.swt;
import com.webcodepro.applecommander.storage.Disk;
import com.webcodepro.applecommander.storage.FilenameFilter;
import com.webcodepro.applecommander.storage.DiskUnrecognizedException;
import com.webcodepro.applecommander.storage.FormattedDisk;
import com.webcodepro.applecommander.storage.*;
import com.webcodepro.applecommander.ui.AppleCommander;
import com.webcodepro.applecommander.ui.UiBundle;
import com.webcodepro.applecommander.ui.UserPreferences;
@@ -32,6 +29,8 @@ import com.webcodepro.applecommander.ui.swt.wizard.comparedisks.CompareDisksWiza
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 org.eclipse.swt.SWT;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
@@ -86,12 +85,16 @@ public class SwtAppleCommander implements Listener {
*/
public void open(String fullpath) {
try {
Disk disk = new Disk(fullpath);
FormattedDisk[] formattedDisks = disk.getFormattedDisks();
DiskWindow window = new DiskWindow(shell, formattedDisks, imageManager);
window.open();
} catch (DiskUnrecognizedException e) {
showUnrecognizedDiskFormatMessage(fullpath);
Source source = Sources.create(fullpath).orElseThrow();
DiskFactory.Context ctx = Disks.inspect(source);
FormattedDisk[] formattedDisks = ctx.disks.toArray(new FormattedDisk[0]);
if (formattedDisks.length > 0) {
DiskWindow window = new DiskWindow(shell, formattedDisks, imageManager);
window.open();
}
else {
showUnrecognizedDiskFormatMessage(fullpath);
}
} catch (Exception ignored) {
ignored.printStackTrace();
showUnexpectedErrorMessage(fullpath);