Updating FormattedDisk API to support conversion between ProDOS file types and native file types; updated UI to use this API for imports (specifically for AppleSingle archives) in order to set the correct native file type. Fixed glitch in UI where it assumed that the file type was always found in the known list of file types. #128

This commit is contained in:
Rob Greene 2023-10-27 14:27:29 -05:00
parent 1c86c39ed2
commit a375e25c66
12 changed files with 241 additions and 162 deletions

View File

@ -19,14 +19,15 @@
*/
package com.webcodepro.applecommander.storage;
import com.webcodepro.applecommander.storage.physical.ImageOrder;
import com.webcodepro.applecommander.util.TextBundle;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import com.webcodepro.applecommander.storage.physical.ImageOrder;
import com.webcodepro.applecommander.util.TextBundle;
/**
* Abstract representation of a formatted Apple2 disk (floppy, 800k, hard disk).
@ -404,4 +405,15 @@ public abstract class FormattedDisk extends Disk implements DirectoryEntry {
* Gives an indication on how this disk's geometry should be handled.
*/
public abstract DiskGeometry getDiskGeometry();
/**
* Provides conversation from a given ProDOS file type since as it is common across
* many archiving tools.
*/
public abstract String fromProdosFiletype(String prodosFiletype);
/**
* Provides conversation to a given ProDOS file type since as it is common across
* many archiving tools.
*/
public abstract String toProdosFiletype(String nativeFiletype);
}

View File

@ -19,22 +19,13 @@
*/
package com.webcodepro.applecommander.storage.os.cpm;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
import com.webcodepro.applecommander.storage.DirectoryEntry;
import com.webcodepro.applecommander.storage.DiskFullException;
import com.webcodepro.applecommander.storage.DiskGeometry;
import com.webcodepro.applecommander.storage.FileEntry;
import com.webcodepro.applecommander.storage.FormattedDisk;
import com.webcodepro.applecommander.storage.StorageBundle;
import com.webcodepro.applecommander.storage.*;
import com.webcodepro.applecommander.storage.physical.ImageOrder;
import com.webcodepro.applecommander.util.AppleUtil;
import com.webcodepro.applecommander.util.TextBundle;
import java.util.*;
/**
* Manages a disk that is in the Apple CP/M format.
* <p>
@ -565,4 +556,29 @@ public class CpmFormatDisk extends FormattedDisk {
public DiskGeometry getDiskGeometry() {
return DiskGeometry.TRACK_SECTOR;
}
/**
* Provides conversation from a given ProDOS file type since as it is common across
* many archiving tools.
*/
@Override
public String fromProdosFiletype(String prodosFiletype) {
if ("TXT".equalsIgnoreCase(prodosFiletype)) {
return "TXT";
}
return "BIN";
}
/**
* Provides conversation to a given ProDOS file type since as it is common across
* many archiving tools.
*/
@Override
public String toProdosFiletype(String nativeFiletype) {
for (String textFiletype : CpmFileEntry.TEXT_FILETYPES) {
if (textFiletype.equalsIgnoreCase(nativeFiletype)) {
return "TXT";
}
}
return "BIN";
}
}

View File

@ -19,23 +19,13 @@
*/
package com.webcodepro.applecommander.storage.os.dos33;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.HashSet;
import com.webcodepro.applecommander.storage.DirectoryEntry;
import com.webcodepro.applecommander.storage.DiskException;
import com.webcodepro.applecommander.storage.DiskCorruptException;
import com.webcodepro.applecommander.storage.DiskFullException;
import com.webcodepro.applecommander.storage.DiskGeometry;
import com.webcodepro.applecommander.storage.FileEntry;
import com.webcodepro.applecommander.storage.FormattedDisk;
import com.webcodepro.applecommander.storage.StorageBundle;
import com.webcodepro.applecommander.storage.*;
import com.webcodepro.applecommander.storage.physical.ImageOrder;
import com.webcodepro.applecommander.util.AppleUtil;
import com.webcodepro.applecommander.util.TextBundle;
import java.util.*;
/**
* Manages a disk that is in Apple DOS 3.3 format.
* <p>
@ -70,11 +60,20 @@ public class DosFormatDisk extends FormattedDisk {
/**
* The list of filetypes available.
*/
private static final String[] filetypes = {
"T", "A", "I", "B", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
"S", "R", "a", "b" //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
private static final String[] FILE_TYPES = {
"T", "A", "I", "B",
"S", "R", "a", "b"
};
private static final Map<String,String> FILE_TYPE_MAPPING = Map.of(
"T", "TXT",
"I", "INT",
"A", "BAS",
"B", "BIN",
"S", "$F1",
"R", "REL",
"a", "$F2",
"b", "$F3"
);
/**
* Use this inner interface for managing the disk usage data.
* This off-loads format-specific implementation to the implementing class.
@ -739,7 +738,7 @@ public class DosFormatDisk extends FormattedDisk {
* specific to each operating system, a simple String is used.
*/
public String[] getFiletypes() {
return filetypes;
return FILE_TYPES;
}
/**
@ -781,4 +780,26 @@ public class DosFormatDisk extends FormattedDisk {
public DiskGeometry getDiskGeometry() {
return DiskGeometry.TRACK_SECTOR;
}
/**
* Provides conversation from a given ProDOS file type since as it is common across
* many archiving tools.
*/
@Override
public String fromProdosFiletype(String prodosFiletype) {
return FILE_TYPE_MAPPING.entrySet()
.stream()
.filter(e -> e.getValue().equals(prodosFiletype))
.map(Map.Entry::getKey)
.findFirst()
.orElse("B");
}
/**
* Provides conversation to a given ProDOS file type since as it is common across
* many archiving tools.
*/
@Override
public String toProdosFiletype(String nativeFiletype) {
return FILE_TYPE_MAPPING.getOrDefault(nativeFiletype, "BIN");
}
}

View File

@ -19,19 +19,14 @@
*/
package com.webcodepro.applecommander.storage.os.gutenberg;
import java.util.ArrayList;
import java.util.List;
import com.webcodepro.applecommander.storage.DirectoryEntry;
import com.webcodepro.applecommander.storage.DiskFullException;
import com.webcodepro.applecommander.storage.DiskGeometry;
import com.webcodepro.applecommander.storage.FileEntry;
import com.webcodepro.applecommander.storage.FormattedDisk;
import com.webcodepro.applecommander.storage.StorageBundle;
import com.webcodepro.applecommander.storage.*;
import com.webcodepro.applecommander.storage.physical.ImageOrder;
import com.webcodepro.applecommander.util.AppleUtil;
import com.webcodepro.applecommander.util.TextBundle;
import java.util.ArrayList;
import java.util.List;
/**
* Manages a disk that is in Gutenberg Word Processor format.
* <p>
@ -707,4 +702,21 @@ public class GutenbergFormatDisk extends FormattedDisk {
public DiskGeometry getDiskGeometry() {
return DiskGeometry.TRACK_SECTOR;
}
/**
* Provides conversation from a given ProDOS file type since as it is common across
* many archiving tools.
*/
@Override
public String fromProdosFiletype(String prodosFiletype) {
return "T";
}
/**
* Provides conversation to a given ProDOS file type since as it is common across
* many archiving tools.
*/
@Override
public String toProdosFiletype(String nativeFiletype) {
return "TXT";
}
}

View File

@ -19,19 +19,14 @@
*/
package com.webcodepro.applecommander.storage.os.nakedos;
import java.util.ArrayList;
import java.util.List;
import com.webcodepro.applecommander.storage.DirectoryEntry;
import com.webcodepro.applecommander.storage.DiskFullException;
import com.webcodepro.applecommander.storage.DiskGeometry;
import com.webcodepro.applecommander.storage.FileEntry;
import com.webcodepro.applecommander.storage.FormattedDisk;
import com.webcodepro.applecommander.storage.StorageBundle;
import com.webcodepro.applecommander.storage.*;
import com.webcodepro.applecommander.storage.physical.ImageOrder;
import com.webcodepro.applecommander.util.AppleUtil;
import com.webcodepro.applecommander.util.TextBundle;
import java.util.ArrayList;
import java.util.List;
/**
* Manages a disk that is in NakedOS format.
* <p>
@ -545,4 +540,21 @@ public class NakedosFormatDisk extends FormattedDisk {
public DiskGeometry getDiskGeometry() {
return DiskGeometry.TRACK_SECTOR;
}
/**
* Provides conversation from a given ProDOS file type since as it is common across
* many archiving tools.
*/
@Override
public String fromProdosFiletype(String prodosFiletype) {
return "B";
}
/**
* Provides conversation to a given ProDOS file type since as it is common across
* many archiving tools.
*/
@Override
public String toProdosFiletype(String nativeFiletype) {
return "BIN";
}
}

View File

@ -21,21 +21,13 @@
*/
package com.webcodepro.applecommander.storage.os.pascal;
import java.util.ArrayList;
import java.util.BitSet;
import java.util.Date;
import java.util.List;
import com.webcodepro.applecommander.storage.DirectoryEntry;
import com.webcodepro.applecommander.storage.DiskFullException;
import com.webcodepro.applecommander.storage.DiskGeometry;
import com.webcodepro.applecommander.storage.FileEntry;
import com.webcodepro.applecommander.storage.FormattedDisk;
import com.webcodepro.applecommander.storage.StorageBundle;
import com.webcodepro.applecommander.storage.*;
import com.webcodepro.applecommander.storage.physical.ImageOrder;
import com.webcodepro.applecommander.util.AppleUtil;
import com.webcodepro.applecommander.util.TextBundle;
import java.util.*;
/**
* Manages a disk that is in the Pascal format.
* <p>
@ -58,15 +50,31 @@ public class PascalFormatDisk extends FormattedDisk {
/**
* The known filetypes for a Pascal disk.
*/
private static final String[] filetypes = {
"xdskfile", //$NON-NLS-1$
private static final String[] FILE_TYPES = {
"xdskfile",
CODEFILE,
TEXTFILE,
"INFO", //$NON-NLS-1$
"INFO",
DATAFILE,
"GRAF", //$NON-NLS-1$
"FOTO", //$NON-NLS-1$
"securedir" }; //$NON-NLS-1$
"GRAF",
"FOTO",
"securedir"
};
private static final Map<String,String> FILE_TYPE_MAP = Map.of(
// Pascal => Prodos
"xdskfile", "BAD",
CODEFILE, "BIN",
TEXTFILE, "TXT",
"INFO", "TXT",
DATAFILE, "BIN",
"GRAF", "BIN",
"FOTO", "BIN",
"securedir", "BIN",
// Prodos => Pascal
"BIN", DATAFILE,
"TXT", TEXTFILE
);
/**
* Use this inner interface for managing the disk usage data.
@ -624,7 +632,7 @@ public class PascalFormatDisk extends FormattedDisk {
* specific to each operating system, a simple String is used.
*/
public String[] getFiletypes() {
return filetypes;
return FILE_TYPES;
}
/**
@ -675,4 +683,21 @@ public class PascalFormatDisk extends FormattedDisk {
public DiskGeometry getDiskGeometry() {
return DiskGeometry.BLOCK;
}
/**
* Provides conversation from a given ProDOS file type since as it is common across
* many archiving tools.
*/
@Override
public String fromProdosFiletype(String prodosFiletype) {
return FILE_TYPE_MAP.getOrDefault(prodosFiletype, DATAFILE);
}
/**
* Provides conversation to a given ProDOS file type since as it is common across
* many archiving tools.
*/
@Override
public String toProdosFiletype(String nativeFiletype) {
return FILE_TYPE_MAP.getOrDefault(nativeFiletype, "BIN");
}
}

View File

@ -19,27 +19,15 @@
*/
package com.webcodepro.applecommander.storage.os.prodos;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Properties;
import java.util.Set;
import java.util.HashSet;
import com.webcodepro.applecommander.storage.DirectoryEntry;
import com.webcodepro.applecommander.storage.DiskException;
import com.webcodepro.applecommander.storage.DiskCorruptException;
import com.webcodepro.applecommander.storage.DiskFullException;
import com.webcodepro.applecommander.storage.DiskGeometry;
import com.webcodepro.applecommander.storage.FileEntry;
import com.webcodepro.applecommander.storage.FormattedDisk;
import com.webcodepro.applecommander.storage.StorageBundle;
import com.webcodepro.applecommander.storage.*;
import com.webcodepro.applecommander.storage.physical.ImageOrder;
import com.webcodepro.applecommander.util.AppleUtil;
import com.webcodepro.applecommander.util.TextBundle;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;
/**
* Manages a disk that is in the ProDOS format.
* <p>
@ -1469,4 +1457,21 @@ public class ProdosFormatDisk extends FormattedDisk {
public DiskGeometry getDiskGeometry() {
return DiskGeometry.BLOCK;
}
/**
* Provides conversation from a given ProDOS file type since as it is common across
* many archiving tools.
*/
@Override
public String fromProdosFiletype(String prodosFiletype) {
return prodosFiletype;
};
/**
* Provides conversation to a given ProDOS file type since as it is common across
* many archiving tools.
*/
@Override
public String toProdosFiletype(String nativeFiletype) {
return nativeFiletype;
};
}

View File

@ -19,21 +19,17 @@
*/
package com.webcodepro.applecommander.storage.os.rdos;
import java.util.ArrayList;
import java.util.BitSet;
import java.util.List;
import com.webcodepro.applecommander.storage.DirectoryEntry;
import com.webcodepro.applecommander.storage.DiskFullException;
import com.webcodepro.applecommander.storage.DiskGeometry;
import com.webcodepro.applecommander.storage.FileEntry;
import com.webcodepro.applecommander.storage.FormattedDisk;
import com.webcodepro.applecommander.storage.StorageBundle;
import com.webcodepro.applecommander.storage.*;
import com.webcodepro.applecommander.storage.physical.ImageOrder;
import com.webcodepro.applecommander.storage.physical.ProdosOrder;
import com.webcodepro.applecommander.util.AppleUtil;
import com.webcodepro.applecommander.util.TextBundle;
import java.util.ArrayList;
import java.util.BitSet;
import java.util.List;
import java.util.Map;
/**
* Manages a disk that is in the RDOS format.
* <p>
@ -79,7 +75,12 @@ public class RdosFormatDisk extends FormattedDisk {
/**
* The known filetypes for a RDOS disk.
*/
public static final String[] filetypes = { "B", "A", "T" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
public static final String[] FILE_TYPES = { "B", "A", "T" };
private static final Map<String,String> FILE_TYPE_MAPPING = Map.of(
"T", "TXT",
"A", "BAS",
"B", "BIN"
);
/**
* 13 sectors for RDOS 2.1/3.2, native sectoring (16) for RDOS 3.3
@ -517,7 +518,7 @@ public class RdosFormatDisk extends FormattedDisk {
* specific to each operating system, a simple String is used.
*/
public String[] getFiletypes() {
return filetypes;
return FILE_TYPES;
}
/**
@ -570,4 +571,26 @@ public class RdosFormatDisk extends FormattedDisk {
public DiskGeometry getDiskGeometry() {
return DiskGeometry.TRACK_SECTOR;
}
/**
* Provides conversation from a given ProDOS file type since as it is common across
* many archiving tools.
*/
@Override
public String fromProdosFiletype(String prodosFiletype) {
return FILE_TYPE_MAPPING.entrySet()
.stream()
.filter(e -> e.getValue().equals(prodosFiletype))
.map(Map.Entry::getKey)
.findFirst()
.orElse("B");
}
/**
* Provides conversation to a given ProDOS file type since as it is common across
* many archiving tools.
*/
@Override
public String toProdosFiletype(String nativeFiletype) {
return FILE_TYPE_MAPPING.getOrDefault(nativeFiletype, "BIN");
}
}

View File

@ -19,29 +19,14 @@
*/
package com.webcodepro.applecommander.util.readerwriter;
import java.util.Map;
import java.util.Optional;
import com.webcodepro.applecommander.storage.DiskFullException;
import com.webcodepro.applecommander.storage.os.dos33.DosFileEntry;
import com.webcodepro.applecommander.storage.os.dos33.DosFormatDisk;
import com.webcodepro.applecommander.util.AppleUtil;
import java.util.Optional;
public class DosFileEntryReaderWriter implements FileEntryReader, FileEntryWriter {
private static final Map<String,String> FILE_TYPES;
static {
FILE_TYPES = Map.of(
"T", "TXT",
"I", "INT",
"A", "BAS",
"B", "BIN",
"S", "$F1",
"R", "REL",
"a", "$F2",
"b", "$F3"
);
}
private DosFileEntry fileEntry;
public DosFileEntryReaderWriter(DosFileEntry fileEntry) {
@ -62,17 +47,13 @@ public class DosFileEntryReaderWriter implements FileEntryReader, FileEntryWrite
@Override
public Optional<String> getProdosFiletype() {
return Optional.ofNullable(FILE_TYPES.get(fileEntry.getFiletype()));
String prodosFiletype = fileEntry.getFormattedDisk().toProdosFiletype(fileEntry.getFiletype());
return Optional.ofNullable(prodosFiletype);
}
@Override
public void setProdosFiletype(String filetype) {
String dosFileType = FILE_TYPES.entrySet()
.stream()
.filter(e -> e.getValue().equals(filetype))
.map(Map.Entry::getKey)
.findFirst()
.orElse("B");
fileEntry.setFiletype(dosFileType);
String dosFiletype = fileEntry.getFormattedDisk().fromProdosFiletype(filetype);
fileEntry.setFiletype(dosFiletype);
}
@Override

View File

@ -19,35 +19,16 @@
*/
package com.webcodepro.applecommander.util.readerwriter;
import java.util.Date;
import java.util.Map;
import java.util.Optional;
import com.webcodepro.applecommander.storage.DiskFullException;
import com.webcodepro.applecommander.storage.filters.PascalTextFileFilter;
import com.webcodepro.applecommander.storage.os.pascal.PascalFileEntry;
import java.util.Date;
import java.util.Optional;
public class PascalFileEntryReaderWriter implements FileEntryReader, FileEntryWriter {
private static final PascalTextFileFilter TEXT_FILTER = new PascalTextFileFilter();
private static final Map<String,String> FILE_TYPES;
static {
FILE_TYPES = Map.of(
// Pascal => Prodos
"xdskfile", "BAD", // TODO we should skip bad block files
"CODE", "BIN", // TODO is there an address?
"TEXT", "TXT",
"INFO", "TXT", // TODO We should skip debugger info
"DATA", "BIN",
"GRAF", "BIN", // TODO compressed graphics image
"FOTO", "BIN", // TODO screen image
"securedir", "BIN", // TODO is this even implemented
// Prodos => Pascal
"BIN", "DATA",
"TXT", "TEXT"
);
}
private PascalFileEntry fileEntry;
public PascalFileEntryReaderWriter(PascalFileEntry fileEntry) {
@ -65,11 +46,11 @@ public class PascalFileEntryReaderWriter implements FileEntryReader, FileEntryWr
@Override
public Optional<String> getProdosFiletype() {
return Optional.ofNullable(FILE_TYPES.get(fileEntry.getFiletype()));
return Optional.ofNullable(fileEntry.getFormattedDisk().toProdosFiletype(fileEntry.getFiletype()));
}
@Override
public void setProdosFiletype(String filetype) {
fileEntry.setFiletype(FILE_TYPES.getOrDefault(filetype, "DATA"));
fileEntry.setFiletype(fileEntry.getFormattedDisk().fromProdosFiletype(filetype));
}
@Override

View File

@ -19,21 +19,11 @@
*/
package com.webcodepro.applecommander.util.readerwriter;
import java.util.Map;
import java.util.Optional;
import com.webcodepro.applecommander.storage.os.rdos.RdosFileEntry;
import java.util.Optional;
public class RdosFileEntryReader implements FileEntryReader {
private static final Map<String,String> FILE_TYPES;
static {
FILE_TYPES = Map.of(
"T", "TXT",
"A", "BAS",
"B", "BIN"
);
}
private RdosFileEntry fileEntry;
public RdosFileEntryReader(RdosFileEntry fileEntry) {
@ -52,7 +42,7 @@ public class RdosFileEntryReader implements FileEntryReader {
@Override
public Optional<String> getProdosFiletype() {
return Optional.ofNullable(FILE_TYPES.get(fileEntry.getFiletype()));
return Optional.ofNullable(fileEntry.getFormattedDisk().toProdosFiletype(fileEntry.getFiletype()));
}
@Override

View File

@ -211,7 +211,8 @@ public class ImportSelectFilesWizardPane extends WizardPane {
AppleSingle as = AppleSingle.read(data);
suggestedFilename = Optional.ofNullable(as.getRealName())
.orElse(suggestedFilename);
suggestedFiletype = ProdosFormatDisk.getFiletype(as.getProdosFileInfo().getFileType());
suggestedFiletype = wizard.getDisk().fromProdosFiletype(
ProdosFormatDisk.getFiletype(as.getProdosFileInfo().getFileType()));
suggestedAddress = Optional.ofNullable(as.getProdosFileInfo())
.map(ProdosFileInfo::getAuxType)
.orElse(suggestedAddress);
@ -285,7 +286,7 @@ public class ImportSelectFilesWizardPane extends WizardPane {
label.setText(textBundle.get("FiletypeLabel")); //$NON-NLS-1$
final Combo filetypes = new Combo(dialog, SWT.BORDER | SWT.READ_ONLY);
filetypes.setItems(wizard.getDisk().getFiletypes());
if (spec.hasFiletype()) {
if (spec.hasFiletype() && filetypes.indexOf(spec.getFiletype()) != -1) {
filetypes.select(filetypes.indexOf(spec.getFiletype()));
}