diff --git a/src/main/java/com/webcodepro/applecommander/storage/DirectoryEntry.java b/src/main/java/com/webcodepro/applecommander/storage/DirectoryEntry.java index 3934e8b..6e4d248 100644 --- a/src/main/java/com/webcodepro/applecommander/storage/DirectoryEntry.java +++ b/src/main/java/com/webcodepro/applecommander/storage/DirectoryEntry.java @@ -28,6 +28,9 @@ import java.util.List; *

* Date Created: Mar 2, 2003 * @author Rob Greene + * + * Changed at: Dec 1, 2017 + * @author Lisias Toledo */ public interface DirectoryEntry { /** @@ -37,17 +40,17 @@ public interface DirectoryEntry { * return value should always be a list - a directory * with 0 entries returns an empty list. */ - public List getFiles(); + public List getFiles() throws DiskException; /** * Create a new FileEntry. */ - public FileEntry createFile() throws DiskFullException; - + public FileEntry createFile() throws DiskException; + /** * Create a new DirectoryEntry. */ - public DirectoryEntry createDirectory(String name) throws DiskFullException; + public DirectoryEntry createDirectory(String name) throws DiskException; /** * Identify if additional directories can be created. This @@ -56,7 +59,7 @@ public interface DirectoryEntry { * to writing. */ public boolean canCreateDirectories(); - + /** * Indicates if this disk image can create a file. * If not, the reason may be as simple as it has not beem implemented diff --git a/src/main/java/com/webcodepro/applecommander/storage/Disk.java b/src/main/java/com/webcodepro/applecommander/storage/Disk.java index 41896ec..fb01ffc 100644 --- a/src/main/java/com/webcodepro/applecommander/storage/Disk.java +++ b/src/main/java/com/webcodepro/applecommander/storage/Disk.java @@ -369,10 +369,10 @@ public class Disk { /** * Determine type of disk, and return the appropriate - * FormattedDisk object. Returns null if none are - * recognized. + * FormattedDisk object. Throws an Exception if none is recognized. + * @throws DiskUnrecognizedException */ - public FormattedDisk[] getFormattedDisks() { + public FormattedDisk[] getFormattedDisks() throws DiskUnrecognizedException { if (isProdosFormat()) { return new FormattedDisk[] { new ProdosFormatDisk(filename, imageOrder) }; @@ -407,7 +407,7 @@ public class Disk { return new FormattedDisk[] { new GutenbergFormatDisk(filename, imageOrder) }; } - return null; + throw new DiskUnrecognizedException(filename); } /** diff --git a/src/main/java/com/webcodepro/applecommander/storage/DiskCorruptException.java b/src/main/java/com/webcodepro/applecommander/storage/DiskCorruptException.java new file mode 100644 index 0000000..4863354 --- /dev/null +++ b/src/main/java/com/webcodepro/applecommander/storage/DiskCorruptException.java @@ -0,0 +1,62 @@ +/* + * AppleCommander - An Apple ][ image utility. + * Copyright (C) 2002 by Robert Greene + * 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; + +/** + * A DiskCorruptException is thrown during the disk's data structures are corrupted + * beyound hope of automatic recovering. + *
+ * Created on Nov 30, 2017. + * @author Lisias Toledo + */ +public class DiskCorruptException extends DiskException { + + private static final long serialVersionUID = 0xFFFFFFFF80000000L; + + public enum Kind { + RECURSIVE_DIRECTORY_STRUCTURE { + public String toString() { + return "DiskCorruptException.RecursiveDirectoryStructure"; //$NON-NLS-1$ + }; + } + } + + public final Kind kind; + public final Object offender; + + private DiskCorruptException(final String description, final String imagepath) { + super(description, imagepath); + this.kind = null; + this.offender = null; + } + + /** + * Constructor for DiskFullException. + */ + public DiskCorruptException(final String imagepath, final Kind kind, final Object offender) { + super(kind.toString(), imagepath); + this.kind = kind; + this.offender = offender; + } + + public String toString() { + return super.toString() + " @ " + offender.toString(); + } +} diff --git a/src/main/java/com/webcodepro/applecommander/storage/DiskException.java b/src/main/java/com/webcodepro/applecommander/storage/DiskException.java new file mode 100644 index 0000000..3ef821a --- /dev/null +++ b/src/main/java/com/webcodepro/applecommander/storage/DiskException.java @@ -0,0 +1,41 @@ +/* + * AppleCommander - An Apple ][ image utility. + * Copyright (C) 2002 by Robert Greene + * 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; + +/** + * A DiskException is the base class for Disk Exceptions. + *
+ * Created on Nov 30, 2017. + * @author Lisias Toledo + */ +public abstract class DiskException extends Exception { + + private static final long serialVersionUID = 0xFFFFFFFF80000000L; + + public final String imagepath; + + /** + * Constructor for DiskException. + */ + public DiskException(final String description, final String imagepath) { + super(description); + this.imagepath = imagepath; + } +} diff --git a/src/main/java/com/webcodepro/applecommander/storage/DiskFullException.java b/src/main/java/com/webcodepro/applecommander/storage/DiskFullException.java index 60fa270..40e22da 100644 --- a/src/main/java/com/webcodepro/applecommander/storage/DiskFullException.java +++ b/src/main/java/com/webcodepro/applecommander/storage/DiskFullException.java @@ -25,15 +25,18 @@ package com.webcodepro.applecommander.storage; *
* Created on Dec 23, 2002. * @author Rob Greene + * + * Changed at: Dec 1, 2017 + * @author Lisias Toledo */ -public class DiskFullException extends Exception { +public class DiskFullException extends DiskException { private static final long serialVersionUID = 0xFFFFFFFF80000000L; /** * Constructor for DiskFullException. */ - public DiskFullException(String description) { - super(description); + public DiskFullException(final String description, final String imagepath) { + super(description, imagepath); } } diff --git a/src/main/java/com/webcodepro/applecommander/storage/DiskUnrecognizedException.java b/src/main/java/com/webcodepro/applecommander/storage/DiskUnrecognizedException.java new file mode 100644 index 0000000..6b92f9c --- /dev/null +++ b/src/main/java/com/webcodepro/applecommander/storage/DiskUnrecognizedException.java @@ -0,0 +1,38 @@ +/* + * AppleCommander - An Apple ][ image utility. + * Copyright (C) 2002 by Robert Greene + * 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; + +/** + * A DiskUnrecognizedException is thrown when the Disk Image being opened is not recognized by any image handler. + *
+ * Created at: Jan 8, 2018 + * @author Lisias Toledo + */ +public class DiskUnrecognizedException extends DiskException { + + private static final long serialVersionUID = 0xFFFFFFFF80000000L; + + /** + * Constructor for DiskFullException. + */ + public DiskUnrecognizedException(final String imagepath) { + super("DiskUnrecognizedException", imagepath); + } +} diff --git a/src/main/java/com/webcodepro/applecommander/storage/FormattedDisk.java b/src/main/java/com/webcodepro/applecommander/storage/FormattedDisk.java index d407638..f4c4681 100644 --- a/src/main/java/com/webcodepro/applecommander/storage/FormattedDisk.java +++ b/src/main/java/com/webcodepro/applecommander/storage/FormattedDisk.java @@ -267,7 +267,7 @@ public abstract class FormattedDisk extends Disk implements DirectoryEntry { * Locate a specific file by filename. * Returns a null if specific filename is not located. */ - public FileEntry getFile(String filename) { + public FileEntry getFile(String filename) throws DiskException { List files = getFiles(); return getFile(files, filename.trim()); } @@ -277,7 +277,7 @@ public abstract class FormattedDisk extends Disk implements DirectoryEntry { * Note that in the instance of a system with directories (ie, ProDOS), * this really returns the first file with the given filename. */ - protected FileEntry getFile(List files, String filename) { + protected FileEntry getFile(List files, String filename) throws DiskException { FileEntry theFileEntry = null; if (files != null) { for (int i=0; i * Date created: Oct 4, 2002 12:29:23 AM * @author Rob Greene + * + * Changed at: Dec 1, 2017 + * @author Lisias Toledo */ public class DosFormatDisk extends FormattedDisk { private TextBundle textBundle = StorageBundle.getInstance(); @@ -132,14 +139,22 @@ public class DosFormatDisk extends FormattedDisk { /** * Retrieve a list of files. + * @throws DiskException * @see com.webcodepro.applecommander.storage.FormattedDisk#getFiles() */ - public List getFiles() { + public List getFiles() throws DiskException { List list = new ArrayList<>(); byte[] vtoc = readVtoc(); int track = AppleUtil.getUnsignedByte(vtoc[1]); int sector = AppleUtil.getUnsignedByte(vtoc[2]); + final Set visits = new HashSet<>(); while (sector != 0) { // bug fix: iterate through all catalog _sectors_ + + // Prevents a recursive catalog crawling. + final DosSectorAddress address = new DosSectorAddress(track, sector); + if ( visits.contains(address)) throw new DiskCorruptException(this.getFilename(), DiskCorruptException.Kind.RECURSIVE_DIRECTORY_STRUCTURE, address); + else visits.add(address); + byte[] catalogSector = readSector(track, sector); int offset = 0x0b; while (offset < 0xff) { // iterate through all entries @@ -174,7 +189,9 @@ public class DosFormatDisk extends FormattedDisk { track = catalogSector[1]; sector = catalogSector[2]; } - throw new DiskFullException(textBundle.get("DosFormatDisk.NoMoreSpaceError")); //$NON-NLS-1$ + throw new DiskFullException( + textBundle.get("DosFormatDisk.NoMoreSpaceError") //$NON-NLS-1$ + , this.getFilename()); } /** @@ -457,7 +474,8 @@ public class DosFormatDisk extends FormattedDisk { if (numberOfSectors > getFreeSectors() + fileEntry.getSectorsUsed()) { throw new DiskFullException( textBundle.format("DosFormatDisk.NotEnoughSectorsError", //$NON-NLS-1$ - numberOfSectors, getFreeSectors())); + numberOfSectors, getFreeSectors()) + , this.getFilename()); } // free "old" data and just rewrite stuff... freeSectors(fileEntry); diff --git a/src/main/java/com/webcodepro/applecommander/storage/os/dos33/DosSectorAddress.java b/src/main/java/com/webcodepro/applecommander/storage/os/dos33/DosSectorAddress.java new file mode 100644 index 0000000..b8d160c --- /dev/null +++ b/src/main/java/com/webcodepro/applecommander/storage/os/dos33/DosSectorAddress.java @@ -0,0 +1,56 @@ +/* + * AppleCommander - An Apple ][ image utility. + * Copyright (C) 2002 by Robert Greene + * 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.os.dos33; + +/** + * A Container for DOS 3.3 Sector Addresses. + *
+ * Created on Dec 13, 2017. + * @author Lisias Toledo + */ +public class DosSectorAddress { + + public final Integer track; + public final Integer sector; + + public DosSectorAddress(int track, int sector) { + this.track = track; + this.sector = sector; + } + + public String toString() { + return "Track:" + this.track + ", Sector:" + this.sector; + } + + public boolean equals(final Object other){ + if(other == null) return false; + if(!(other instanceof DosSectorAddress)) return false; + + final DosSectorAddress o = (DosSectorAddress) other; + return this.track == o.track && this.sector == o.sector; + } + + public int hashCode() { + int result = 17; + result = 31 * result + this.track.hashCode(); + result = 31 * result + this.sector.hashCode(); + return result; + } +} diff --git a/src/main/java/com/webcodepro/applecommander/storage/os/gutenberg/GutenbergFormatDisk.java b/src/main/java/com/webcodepro/applecommander/storage/os/gutenberg/GutenbergFormatDisk.java index aa1459c..2cb8cbb 100644 --- a/src/main/java/com/webcodepro/applecommander/storage/os/gutenberg/GutenbergFormatDisk.java +++ b/src/main/java/com/webcodepro/applecommander/storage/os/gutenberg/GutenbergFormatDisk.java @@ -172,7 +172,9 @@ public class GutenbergFormatDisk extends FormattedDisk { track = catalogSector[1]; sector = catalogSector[2]; } - throw new DiskFullException(textBundle.get("DosFormatDisk.NoMoreSpaceError")); //$NON-NLS-1$ + throw new DiskFullException( + textBundle.get("DosFormatDisk.NoMoreSpaceError") //$NON-NLS-1$ + , this.getFilename()); } /** @@ -436,7 +438,8 @@ public class GutenbergFormatDisk extends FormattedDisk { if (numberOfSectors > getFreeSectors() + fileEntry.getSectorsUsed()) { throw new DiskFullException( textBundle.format("DosFormatDisk.NotEnoughSectorsError", //$NON-NLS-1$ - numberOfSectors, getFreeSectors())); + numberOfSectors, getFreeSectors()) + , this.getFilename()); } // free "old" data and just rewrite stuff... // freeSectors(fileEntry); (not going to work...) diff --git a/src/main/java/com/webcodepro/applecommander/storage/os/pascal/PascalFileEntry.java b/src/main/java/com/webcodepro/applecommander/storage/os/pascal/PascalFileEntry.java index 2de1ea2..a978e80 100644 --- a/src/main/java/com/webcodepro/applecommander/storage/os/pascal/PascalFileEntry.java +++ b/src/main/java/com/webcodepro/applecommander/storage/os/pascal/PascalFileEntry.java @@ -351,7 +351,7 @@ public class PascalFileEntry implements FileEntry { volEntry.setFileCount(count - 2); dir.set(0, volEntry); disk.putDirectory(dir); - throw new DiskFullException(s); + throw new DiskFullException(s, this.disk.getFilename()); } } diff --git a/src/main/java/com/webcodepro/applecommander/storage/os/pascal/PascalFormatDisk.java b/src/main/java/com/webcodepro/applecommander/storage/os/pascal/PascalFormatDisk.java index 3a6d135..82fab46 100644 --- a/src/main/java/com/webcodepro/applecommander/storage/os/pascal/PascalFormatDisk.java +++ b/src/main/java/com/webcodepro/applecommander/storage/os/pascal/PascalFormatDisk.java @@ -233,7 +233,9 @@ public class PascalFormatDisk extends FormattedDisk { putDirectory(dir); return entry; } else { - throw new DiskFullException(textBundle.get("PascalFormatDisk.DiskFull")); //$NON-NLS-1$ + throw new DiskFullException( + textBundle.get("PascalFormatDisk.DiskFull") //$NON-NLS-1$ + , this.getFilename()); } } diff --git a/src/main/java/com/webcodepro/applecommander/storage/os/prodos/ProdosBlockAddress.java b/src/main/java/com/webcodepro/applecommander/storage/os/prodos/ProdosBlockAddress.java new file mode 100644 index 0000000..2f8d3f1 --- /dev/null +++ b/src/main/java/com/webcodepro/applecommander/storage/os/prodos/ProdosBlockAddress.java @@ -0,0 +1,39 @@ +/* + * AppleCommander - An Apple ][ image utility. + * Copyright (C) 2002 by Robert Greene + * 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.os.prodos; + +/** + * A Container for DOS 3.3 Sector Addresses. + *
+ * Created on Dec 13, 2017. + * @author Lisias Toledo + */ +public class ProdosBlockAddress { + + public final Integer number; + + public ProdosBlockAddress(int number) { + this.number = number; + } + + public String toString() { + return "Block:" + this.number; + } +} diff --git a/src/main/java/com/webcodepro/applecommander/storage/os/prodos/ProdosDirectoryEntry.java b/src/main/java/com/webcodepro/applecommander/storage/os/prodos/ProdosDirectoryEntry.java index 3ebc356..bee6f14 100644 --- a/src/main/java/com/webcodepro/applecommander/storage/os/prodos/ProdosDirectoryEntry.java +++ b/src/main/java/com/webcodepro/applecommander/storage/os/prodos/ProdosDirectoryEntry.java @@ -22,6 +22,7 @@ package com.webcodepro.applecommander.storage.os.prodos; import java.util.List; import com.webcodepro.applecommander.storage.DirectoryEntry; +import com.webcodepro.applecommander.storage.DiskException; import com.webcodepro.applecommander.storage.DiskFullException; import com.webcodepro.applecommander.storage.FileEntry; import com.webcodepro.applecommander.storage.StorageBundle; @@ -32,21 +33,24 @@ import com.webcodepro.applecommander.util.TextBundle; *

* Date Created: Mar 2, 2003 * @author Rob Greene + * + * Changed at: Dec 1, 2017 + * @author Lisias Toledo */ public class ProdosDirectoryEntry extends ProdosFileEntry implements DirectoryEntry { private TextBundle textBundle = StorageBundle.getInstance(); private ProdosSubdirectoryHeader subdirectoryHeader; - + /** * Constructor for ProdosDirectoryEntry. */ - public ProdosDirectoryEntry(ProdosFormatDisk disk, int block, int offset, + public ProdosDirectoryEntry(ProdosFormatDisk disk, int block, int offset, ProdosSubdirectoryHeader subdirectoryHeader) { super(disk, block, offset); this.subdirectoryHeader = subdirectoryHeader; subdirectoryHeader.setProdosDirectoryEntry(this); } - + /** * Get the subdirectory header. */ @@ -60,8 +64,9 @@ public class ProdosDirectoryEntry extends ProdosFileEntry implements DirectoryEn * value should be null. If this a directory, the * return value should always be a list - a directory * with 0 entries returns an empty list. + * @throws DiskException */ - public List getFiles() { + public List getFiles() throws DiskException { return getDisk().getFiles(getSubdirectoryHeader().getFileEntryBlock()); } diff --git a/src/main/java/com/webcodepro/applecommander/storage/os/prodos/ProdosDiskSizeDoesNotMatchException.java b/src/main/java/com/webcodepro/applecommander/storage/os/prodos/ProdosDiskSizeDoesNotMatchException.java index c7eb317..b501ad8 100644 --- a/src/main/java/com/webcodepro/applecommander/storage/os/prodos/ProdosDiskSizeDoesNotMatchException.java +++ b/src/main/java/com/webcodepro/applecommander/storage/os/prodos/ProdosDiskSizeDoesNotMatchException.java @@ -37,7 +37,7 @@ public class ProdosDiskSizeDoesNotMatchException extends DiskFullException { /** * Constructor for ProdosDiskSizeDoesNotMatchException. */ - public ProdosDiskSizeDoesNotMatchException(String description) { - super(description); + public ProdosDiskSizeDoesNotMatchException(String description, final String imagepath) { + super(description, imagepath); } } diff --git a/src/main/java/com/webcodepro/applecommander/storage/os/prodos/ProdosFormatDisk.java b/src/main/java/com/webcodepro/applecommander/storage/os/prodos/ProdosFormatDisk.java index aef90a5..973882a 100644 --- a/src/main/java/com/webcodepro/applecommander/storage/os/prodos/ProdosFormatDisk.java +++ b/src/main/java/com/webcodepro/applecommander/storage/os/prodos/ProdosFormatDisk.java @@ -25,8 +25,12 @@ 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.FileEntry; import com.webcodepro.applecommander.storage.FormattedDisk; @@ -40,6 +44,9 @@ import com.webcodepro.applecommander.util.TextBundle; *

* Date created: Oct 3, 2002 11:45:25 PM * @author Rob Greene + * + * Changed at: Dec 1, 2017 + * @author Lisias Toledo */ public class ProdosFormatDisk extends FormattedDisk { private TextBundle textBundle = StorageBundle.getInstance(); @@ -250,14 +257,15 @@ public class ProdosFormatDisk extends FormattedDisk { } blockNumber = nextBlockNumber; } - throw new DiskFullException(textBundle.get("ProdosFormatDisk.UnableToAllocateSpaceError")); //$NON-NLS-1$ + throw new DiskFullException(textBundle.get("ProdosFormatDisk.UnableToAllocateSpaceError"), this.getFilename()); //$NON-NLS-1$ } /** * Retrieve a list of files. + * @throws DiskException * @see com.webcodepro.applecommander.storage.FormattedDisk#getFiles() */ - public List getFiles() { + public List getFiles() throws DiskException { return getFiles(VOLUME_DIRECTORY_BLOCK); } @@ -265,9 +273,14 @@ public class ProdosFormatDisk extends FormattedDisk { * Build a list of files, starting in the given block number. * This works for the master as well as the subdirectories. */ - protected List getFiles(int blockNumber) { + protected List getFiles(int blockNumber) throws DiskException { List files = new ArrayList<>(); + final Set visits = new HashSet<>(); while (blockNumber != 0) { + // Prevents a recursive catalog crawling. + if ( visits.contains(blockNumber)) throw new DiskCorruptException(this.getFilename(), DiskCorruptException.Kind.RECURSIVE_DIRECTORY_STRUCTURE, new ProdosBlockAddress(blockNumber)); + else visits.add(blockNumber); + byte[] block = readBlock(blockNumber); int offset = 4; while (offset+ProdosCommonEntry.ENTRY_LENGTH < BLOCK_SIZE) { @@ -643,7 +656,8 @@ public class ProdosFormatDisk extends FormattedDisk { if (numberOfBlocks > getFreeBlocks() + fileEntry.getBlocksUsed()) { throw new DiskFullException(textBundle. format("ProdosFormatDisk.NotEnoughSpaceOnDiskError", //$NON-NLS-1$ - numberOfBlocks, getFreeBlocks())); + numberOfBlocks, getFreeBlocks()) + , this.getFilename()); } // free "old" data and just rewrite stuff... freeBlocks(fileEntry); @@ -748,7 +762,8 @@ public class ProdosFormatDisk extends FormattedDisk { if (numberOfBlocks > getFreeBlocks() + fileEntry.getBlocksUsed()) { throw new DiskFullException(textBundle. format("ProdosFormatDisk.NotEnoughSpaceOnDiskError", //$NON-NLS-1$ - numberOfBlocks, getFreeBlocks())); + numberOfBlocks, getFreeBlocks()) + , this.getFilename()); } // free "old" data and just rewrite stuff... freeBlocks(fileEntry); @@ -915,7 +930,8 @@ public class ProdosFormatDisk extends FormattedDisk { if (numberOfBlocks > getFreeBlocks() + fileEntry.getBlocksUsed()) { throw new DiskFullException(textBundle. format("ProdosFormatDisk.NotEnoughSpaceOnDiskError", //$NON-NLS-1$ - numberOfBlocks, getFreeBlocks())); + numberOfBlocks, getFreeBlocks()) + , this.getFilename()); } // free "old" data and just rewrite stuff... freeBlocks(fileEntry); @@ -1056,12 +1072,14 @@ public class ProdosFormatDisk extends FormattedDisk { return block; } throw new ProdosDiskSizeDoesNotMatchException( - textBundle.get("ProdosFormatDisk.ProdosDiskSizeDoesNotMatchError")); //$NON-NLS-1$ + textBundle.get("ProdosFormatDisk.ProdosDiskSizeDoesNotMatchError") //$NON-NLS-1$ + , this.getFilename()); } block++; } throw new DiskFullException( - textBundle.get("ProdosFormatDisk.NoFreeBlockAvailableError")); //$NON-NLS-1$ + textBundle.get("ProdosFormatDisk.NoFreeBlockAvailableError") //$NON-NLS-1$ + , this.getFilename()); } /** @@ -1410,6 +1428,8 @@ public class ProdosFormatDisk extends FormattedDisk { } blockNumber = nextBlockNumber; } - throw new DiskFullException(textBundle.get("ProdosFormatDisk.UnableToAllocateSpaceError")); //$NON-NLS-1$ + throw new DiskFullException( + textBundle.get("ProdosFormatDisk.UnableToAllocateSpaceError") //$NON-NLS-1$ + , this.getFilename()); } } diff --git a/src/main/java/com/webcodepro/applecommander/storage/os/rdos/RdosFormatDisk.java b/src/main/java/com/webcodepro/applecommander/storage/os/rdos/RdosFormatDisk.java index 408eaef..ef1eeb4 100644 --- a/src/main/java/com/webcodepro/applecommander/storage/os/rdos/RdosFormatDisk.java +++ b/src/main/java/com/webcodepro/applecommander/storage/os/rdos/RdosFormatDisk.java @@ -202,7 +202,7 @@ public class RdosFormatDisk extends FormattedDisk { * Create a new FileEntry. */ public FileEntry createFile() throws DiskFullException { - throw new DiskFullException(textBundle.get("FileCreationNotSupported")); //$NON-NLS-1$ + throw new DiskFullException(textBundle.get("FileCreationNotSupported"), this.getFilename()); //$NON-NLS-1$ } /** diff --git a/src/main/java/com/webcodepro/applecommander/ui/AntTask.java b/src/main/java/com/webcodepro/applecommander/ui/AntTask.java index b116a7a..cbc5a80 100644 --- a/src/main/java/com/webcodepro/applecommander/ui/AntTask.java +++ b/src/main/java/com/webcodepro/applecommander/ui/AntTask.java @@ -26,6 +26,7 @@ import java.io.PrintStream; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.Task; import com.webcodepro.applecommander.storage.Disk; +import com.webcodepro.applecommander.storage.DiskException; import com.webcodepro.applecommander.storage.FormattedDisk; public class AntTask extends Task @@ -107,7 +108,7 @@ public class AntTask extends Task { com.webcodepro.applecommander.ui.ac.deleteFile(_imageName, _fileName); } - catch (IOException io) + catch (IOException|DiskException io) { if (_failonerror) throw new BuildException(io); @@ -121,7 +122,7 @@ public class AntTask extends Task { com.webcodepro.applecommander.ui.ac.setDiskName(_imageName, _volName); } - catch (IOException io) + catch (IOException|DiskException io) { if (_failonerror) throw new BuildException(io); @@ -138,7 +139,7 @@ public class AntTask extends Task else // Assume unlock com.webcodepro.applecommander.ui.ac.setFileLocked(_imageName, _fileName, false); } - catch (IOException io) + catch (IOException|DiskException io) { if (_failonerror) throw new BuildException(io); @@ -220,7 +221,7 @@ public class AntTask extends Task { com.webcodepro.applecommander.ui.ac.getFiles(_imageName, _outputPath); } - catch (IOException io) + catch (IOException|DiskException io) { if (_failonerror) throw new BuildException(io); diff --git a/src/main/java/com/webcodepro/applecommander/ui/ac.java b/src/main/java/com/webcodepro/applecommander/ui/ac.java index ecdf863..3c57965 100644 --- a/src/main/java/com/webcodepro/applecommander/ui/ac.java +++ b/src/main/java/com/webcodepro/applecommander/ui/ac.java @@ -34,7 +34,7 @@ import java.util.List; import com.webcodepro.applecommander.storage.DirectoryEntry; import com.webcodepro.applecommander.storage.Disk; -import com.webcodepro.applecommander.storage.DiskFullException; +import com.webcodepro.applecommander.storage.DiskException; import com.webcodepro.applecommander.storage.FileEntry; import com.webcodepro.applecommander.storage.FileFilter; import com.webcodepro.applecommander.storage.FormattedDisk; @@ -85,6 +85,9 @@ import com.webcodepro.applecommander.util.TextBundle; * * * @author John B. Matthews + * + * Changed at: Dec 1, 2017 + * @author Lisias Toledo */ public class ac { private static TextBundle textBundle = UiBundle.getInstance(); @@ -154,7 +157,7 @@ public class ac { * Put fileName from the local filesytem into the file named fileOnImageName on the disk named imageName; * Note: only volume level supported; input size unlimited. */ - public static void putFile(String fileName, String imageName, String fileOnImageName, String fileType, String address) throws IOException, DiskFullException { + public static void putFile(String fileName, String imageName, String fileOnImageName, String fileType, String address) throws IOException, DiskException { Name name = new Name(fileOnImageName); File file = new File(fileName); if (!file.canRead()) @@ -188,7 +191,7 @@ public class ac { * Note: only volume level supported; input size unlimited. */ static void putFile(String imageName, Name name, String fileType, - String address) throws IOException, DiskFullException { + String address) throws IOException, DiskException { ByteArrayOutputStream buf = new ByteArrayOutputStream(); byte[] inb = new byte[1024]; @@ -225,7 +228,7 @@ public class ac { * Assume a cc65 style four-byte header with start address in bytes 0-1. */ public static void putCC65(String fileName, String imageName, String fileOnImageName, String fileType) - throws IOException, DiskFullException { + throws IOException, DiskException { byte[] header = new byte[4]; if (System.in.read(header, 0, 4) == 4) { @@ -239,7 +242,7 @@ public class ac { * Assume a cc65 style four-byte header with start address in bytes 0-1. */ static void putCC65(String imageName, Name name, String fileType) - throws IOException, DiskFullException { + throws IOException, DiskException { byte[] header = new byte[4]; if (System.in.read(header, 0, 4) == 4) { @@ -253,7 +256,7 @@ public class ac { * This would only make sense for a ProDOS-formatted disk. */ static void putGEOS(String imageName) - throws IOException, DiskFullException { + throws IOException, DiskException { putFile(imageName, new Name("GEOS-Should Be ProDOS"), "GEO", "0"); //$NON-NLS-2$ $NON-NLS-3$ } @@ -261,7 +264,7 @@ public class ac { * Delete the file named fileName from the disk named imageName. */ static void deleteFile(String imageName, String fileName) - throws IOException { + throws IOException, DiskException { Disk disk = new Disk(imageName); Name name = new Name(fileName); if (!disk.isSDK() && !disk.isDC42()) { @@ -287,7 +290,7 @@ public class ac { * filtered according to its type and sent to <stdout>. */ static void getFile(String imageName, String fileName, boolean filter, PrintStream out) - throws IOException { + throws IOException, DiskException { Disk disk = new Disk(imageName); Name name = new Name(fileName); FormattedDisk[] formattedDisks = disk.getFormattedDisks(); @@ -317,7 +320,7 @@ public class ac { /** * Extract all files in the image according to their respective filetype. */ - static void getFiles(String imageName, String directory) throws IOException { + static void getFiles(String imageName, String directory) throws IOException, DiskException { Disk disk = new Disk(imageName); if ((directory != null) && (directory.length() > 0)) { // Add a final directory separator if the user didn't supply one @@ -327,16 +330,16 @@ public class ac { directory = "."+File.separator; } FormattedDisk[] formattedDisks = disk.getFormattedDisks(); - for (int i = 0; i < formattedDisks.length; i++) { + for (int i = 0; i < formattedDisks.length; i++) { FormattedDisk formattedDisk = formattedDisks[i]; - writeFiles(formattedDisk.getFiles(), directory); + writeFiles(formattedDisk.getFiles(), directory); } } /** * Recursive routine to write directory and file entries. */ - static void writeFiles(List files, String directory) throws IOException { + static void writeFiles(List files, String directory) throws IOException, DiskException { Iterator it = files.iterator(); while (it.hasNext()) { FileEntry entry = (FileEntry) it.next(); @@ -352,7 +355,7 @@ public class ac { OutputStream output = new FileOutputStream(file); output.write(buf, 0, buf.length); output.close(); - } else if (entry.isDirectory()) { + } else if (entry.isDirectory()) { writeFiles(((DirectoryEntry) entry).getFiles(),directory+entry.getFilename()+File.separator); } } @@ -364,7 +367,7 @@ public class ac { * file with the given filename. * @deprecated */ - static FileEntry getEntry(List files, String fileName) { + static FileEntry getEntry(List files, String fileName) throws DiskException { FileEntry entry = null; if (files != null) { for (int i = 0; i < files.size(); i++) { @@ -406,6 +409,8 @@ public class ac { new Integer(formattedDisk.getUsedSpace()) })); System.out.println(); } + } catch (DiskException e) { + throw new IOException(e); } catch (RuntimeException e) { System.out.println(args[d] + ": " + e.getMessage()); //$NON-NLS-1$ System.out.println(); @@ -418,7 +423,7 @@ public class ac { * system with directories (e.g. ProDOS), this really returns the first file * with the given filename. */ - static void showFiles(List files, String indent, int display) { + static void showFiles(List files, String indent, int display) throws DiskException { for (int i = 0; i < files.size(); i++) { FileEntry entry = (FileEntry) files.get(i); if (!entry.isDeleted()) { @@ -440,7 +445,7 @@ public class ac { /** * Display information about each disk in args. */ - static void getDiskInfo(String[] args) throws IOException { + 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(); @@ -460,7 +465,7 @@ public class ac { * Set the lockState of the file named fileName on the disk named imageName. * Proposed by David Schmidt. */ - public static void setFileLocked(String imageName, String name, boolean lockState) throws IOException { + public static void setFileLocked(String imageName, String name, boolean lockState) throws IOException, DiskException { setFileLocked(imageName, new Name(name), lockState); } @@ -469,7 +474,7 @@ public class ac { * Proposed by David Schmidt. */ static void setFileLocked(String imageName, Name name, - boolean lockState) throws IOException { + boolean lockState) throws IOException, DiskException { Disk disk = new Disk(imageName); if (!disk.isSDK() && !disk.isDC42()) { FormattedDisk[] formattedDisks = disk.getFormattedDisks(); @@ -494,7 +499,7 @@ public class ac { * Pascal disks; others ignored. Proposed by David Schmidt. */ public static void setDiskName(String imageName, String volName) - throws IOException { + throws IOException, DiskException { Disk disk = new Disk(imageName); if (!disk.isSDK() && !disk.isDC42()) { FormattedDisk[] formattedDisks = disk.getFormattedDisks(); @@ -601,7 +606,7 @@ public class ac { this.name = path[path.length - 1]; } - public FileEntry getEntry(FormattedDisk formattedDisk) { + public FileEntry getEntry(FormattedDisk formattedDisk) throws DiskException { List files = formattedDisk.getFiles(); FileEntry entry = null; for (int i = 0; i < path.length - 1; i++) { @@ -624,7 +629,7 @@ public class ac { return null; } - public FileEntry createEntry(FormattedDisk formattedDisk) throws DiskFullException { + public FileEntry createEntry(FormattedDisk formattedDisk) throws DiskException { if (path.length == 1) { return formattedDisk.createFile(); } diff --git a/src/main/java/com/webcodepro/applecommander/ui/swt/DiskExplorerTab.java b/src/main/java/com/webcodepro/applecommander/ui/swt/DiskExplorerTab.java index f5794e3..6d6a6e1 100644 --- a/src/main/java/com/webcodepro/applecommander/ui/swt/DiskExplorerTab.java +++ b/src/main/java/com/webcodepro/applecommander/ui/swt/DiskExplorerTab.java @@ -26,6 +26,7 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; @@ -71,6 +72,8 @@ import org.eclipse.swt.widgets.TreeItem; import com.webcodepro.applecommander.compiler.ApplesoftCompiler; import com.webcodepro.applecommander.storage.DirectoryEntry; import com.webcodepro.applecommander.storage.Disk; +import com.webcodepro.applecommander.storage.DiskCorruptException; +import com.webcodepro.applecommander.storage.DiskException; import com.webcodepro.applecommander.storage.FileEntry; import com.webcodepro.applecommander.storage.FileEntryComparator; import com.webcodepro.applecommander.storage.FileFilter; @@ -114,6 +117,9 @@ import com.webcodepro.applecommander.util.TextBundle; *

* Date created: Nov 17, 2002 9:46:53 PM * @author Rob Greene + * + * Changed at: Dec 1, 2017 + * @author Lisias Toledo */ public class DiskExplorerTab { private static final char CTRL_C = 'C' - '@'; @@ -224,7 +230,11 @@ public class DiskExplorerTab { * Single-click handler. */ public void widgetSelected(SelectionEvent event) { - changeCurrentFormat(getCurrentFormat()); // minor hack + try { + changeCurrentFormat(getCurrentFormat()); // minor hack + } catch (DiskException e) { + DiskExplorerTab.this.diskWindow.handle(e); + } } /** * Double-click handler. @@ -248,27 +258,35 @@ public class DiskExplorerTab { diskItem.setText(disks[i].getDiskName()); diskItem.setData(disks[i]); directoryTree.setSelection(new TreeItem[] { diskItem }); - + if (disks[i].canHaveDirectories()) { - Iterator files = disks[i].getFiles().iterator(); - while (files.hasNext()) { - FileEntry entry = (FileEntry) files.next(); - if (entry.isDirectory()) { - TreeItem item = new TreeItem(diskItem, SWT.BORDER); - item.setText(entry.getFilename()); - item.setData(entry); - addDirectoriesToTree(item, (DirectoryEntry)entry); + try { + Iterator files = disks[i].getFiles().iterator(); + while (files.hasNext()) { + FileEntry entry = (FileEntry) files.next(); + if (entry.isDirectory()) { + TreeItem item = new TreeItem(diskItem, SWT.BORDER); + item.setText(entry.getFilename()); + item.setData(entry); + addDirectoriesToTree(item, (DirectoryEntry)entry); + } } - } + } catch (DiskException e) { + this.diskWindow.handle(e); + } } } - + computeColumnWidths(FormattedDisk.FILE_DISPLAY_STANDARD); computeColumnWidths(FormattedDisk.FILE_DISPLAY_NATIVE); computeColumnWidths(FormattedDisk.FILE_DISPLAY_DETAIL); formatChanged = true; - fillFileTable(disks[0].getFiles()); + try { + fillFileTable(disks[0].getFiles()); + } catch (DiskException e) { + this.diskWindow.handle(e); + } directoryTree.setSelection(new TreeItem[] { directoryTree.getItems()[0] }); } /** @@ -338,11 +356,15 @@ public class DiskExplorerTab { item.setImage(imageManager.get(ImageManager.ICON_IMPORT_FILE)); item.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent event) { - importFiles(); + try { + importFiles(); + } catch (DiskException e) { + DiskExplorerTab.this.diskWindow.handle(e); + } } }); item.setEnabled(disks[0].canCreateFile() && disks[0].canWriteFileData()); - + return menu; } /** @@ -389,7 +411,11 @@ public class DiskExplorerTab { item.setImage(imageManager.get(ImageManager.ICON_VIEW_FILE)); item.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent event) { - viewFile(null); + try { + viewFile(null); + } catch (DiskException e) { + DiskExplorerTab.this.diskWindow.handle(e); + } } }); @@ -444,7 +470,11 @@ public class DiskExplorerTab { item.setText(textBundle.get("ViewAsTextMenuItem")); //$NON-NLS-1$ item.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent event) { - viewFile(TextFileFilter.class); + try { + viewFile(TextFileFilter.class); + } catch (DiskException e) { + DiskExplorerTab.this.diskWindow.handle(e); + } } }); @@ -452,7 +482,11 @@ public class DiskExplorerTab { item.setText(textBundle.get("VeiwAsGraphicsMenuItem")); //$NON-NLS-1$ item.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent event) { - viewFile(GraphicsFileFilter.class); + try { + viewFile(GraphicsFileFilter.class); + } catch (DiskException e) { + DiskExplorerTab.this.diskWindow.handle(e); + } } }); @@ -879,7 +913,11 @@ public class DiskExplorerTab { * Double-click handler. */ public void widgetDefaultSelected(SelectionEvent event) { - viewFile(null); + try { + viewFile(null); + } catch (DiskException e) { + DiskExplorerTab.this.diskWindow.handle(e); + } } }); TableColumn column = null; @@ -1101,12 +1139,13 @@ public class DiskExplorerTab { } /** * Start the import wizard and import the selected files. + * @throws DiskException */ - protected void importFiles() { + protected void importFiles() throws DiskException { //FIXME: This code has become really ugly! TreeItem treeItem = directoryTree.getSelection()[0]; DirectoryEntry directory = (DirectoryEntry) treeItem.getData(); - ImportWizard wizard = new ImportWizard(shell, + ImportWizard wizard = new ImportWizard(shell, imageManager, directory.getFormattedDisk()); wizard.open(); if (wizard.isWizardCompleted()) { @@ -1201,8 +1240,9 @@ public class DiskExplorerTab { } /** * Helper function for building fileTree. + * @throws DiskException */ - protected void addDirectoriesToTree(TreeItem directoryItem, DirectoryEntry directoryEntry) { + protected void addDirectoriesToTree(TreeItem directoryItem, DirectoryEntry directoryEntry) throws DiskException { Iterator files = directoryEntry.getFiles().iterator(); while (files.hasNext()) { final FileEntry entry = (FileEntry) files.next(); @@ -1228,8 +1268,12 @@ public class DiskExplorerTab { standardFormatToolItem.setToolTipText(textBundle.get("StandardViewHoverText")); //$NON-NLS-1$ standardFormatToolItem.setSelection(true); standardFormatToolItem.addSelectionListener(new SelectionAdapter () { - public void widgetSelected(SelectionEvent e) { - changeCurrentFormat(FormattedDisk.FILE_DISPLAY_STANDARD); + public void widgetSelected(SelectionEvent event) { + try { + changeCurrentFormat(FormattedDisk.FILE_DISPLAY_STANDARD); + } catch (DiskException e) { + DiskExplorerTab.this.diskWindow.handle(e); + } } }); nativeFormatToolItem = new ToolItem(toolBar, SWT.RADIO); @@ -1237,8 +1281,12 @@ public class DiskExplorerTab { nativeFormatToolItem.setText(textBundle.get("NativeViewToolItem")); //$NON-NLS-1$ nativeFormatToolItem.setToolTipText(textBundle.get("NativeViewHoverText")); //$NON-NLS-1$ nativeFormatToolItem.addSelectionListener(new SelectionAdapter () { - public void widgetSelected(SelectionEvent e) { - changeCurrentFormat(FormattedDisk.FILE_DISPLAY_NATIVE); + public void widgetSelected(SelectionEvent event) { + try { + changeCurrentFormat(FormattedDisk.FILE_DISPLAY_NATIVE); + } catch (DiskException e) { + DiskExplorerTab.this.diskWindow.handle(e); + } } }); detailFormatToolItem = new ToolItem(toolBar, SWT.RADIO); @@ -1246,13 +1294,17 @@ public class DiskExplorerTab { detailFormatToolItem.setText(textBundle.get("DetailViewToolItem")); //$NON-NLS-1$ detailFormatToolItem.setToolTipText(textBundle.get("DetailViewHoverText")); //$NON-NLS-1$ detailFormatToolItem.addSelectionListener(new SelectionAdapter () { - public void widgetSelected(SelectionEvent e) { - changeCurrentFormat(FormattedDisk.FILE_DISPLAY_DETAIL); + public void widgetSelected(SelectionEvent event) { + try { + changeCurrentFormat(FormattedDisk.FILE_DISPLAY_DETAIL); + } catch (DiskException e) { + DiskExplorerTab.this.diskWindow.handle(e); + } } }); - + new ToolItem(toolBar, SWT.SEPARATOR); - + showDeletedFilesToolItem = new ToolItem(toolBar, SWT.CHECK); showDeletedFilesToolItem.setImage(imageManager.get(ImageManager.ICON_SHOW_DELETED_FILES)); showDeletedFilesToolItem.setText(textBundle.get("ShowDeletedFilesToolItem")); //$NON-NLS-1$ @@ -1274,11 +1326,15 @@ public class DiskExplorerTab { importToolItem.setToolTipText(textBundle.get("ImportWizardHoverText")); //$NON-NLS-1$ importToolItem.setEnabled(disks[0].canCreateFile() && disks[0].canWriteFileData()); importToolItem.addSelectionListener(new SelectionAdapter () { - public void widgetSelected(SelectionEvent e) { - importFiles(); + public void widgetSelected(SelectionEvent event) { + try { + importFiles(); + } catch (DiskException e) { + DiskExplorerTab.this.diskWindow.handle(e); + } } }); - + exportToolItem = new ToolItem(toolBar, SWT.DROP_DOWN); exportToolItem.setImage(imageManager.get(ImageManager.ICON_EXPORT_FILE)); exportToolItem.setText(textBundle.get("ExportWizardToolItem")); //$NON-NLS-1$ @@ -1315,8 +1371,12 @@ public class DiskExplorerTab { viewFileItem.setEnabled(false); viewFileItem.addSelectionListener(new SelectionAdapter () { public void widgetSelected(SelectionEvent event) { - if (event.detail != SWT.ARROW) { - viewFile(null); + if (event.detail != SWT.ARROW) { + try { + viewFile(null); + } catch (DiskException e) { + DiskExplorerTab.this.diskWindow.handle(e); + } } } }); @@ -1402,8 +1462,9 @@ public class DiskExplorerTab { } /** * Change the current format and refresh the display. + * @throws DiskException */ - protected void changeCurrentFormat(int newFormat) { + protected void changeCurrentFormat(int newFormat) throws DiskException { TreeItem selection = directoryTree.getSelection()[0]; Object data = selection.getData(); DirectoryEntry directory = (DirectoryEntry) data; @@ -1522,8 +1583,9 @@ public class DiskExplorerTab { } /** * Open up the view file window for the currently selected file. + * @throws DiskException */ - protected void viewFile(Class fileFilterClass) { + protected void viewFile(Class fileFilterClass) throws DiskException { FileEntry fileEntry = getSelectedFileEntry(); if (fileEntry.isDeleted()) { SwtUtil.showErrorDialog(shell, textBundle.get("DeleteFileErrorTitle"), //$NON-NLS-1$ @@ -1584,24 +1646,28 @@ public class DiskExplorerTab { public void handleEvent(Event event) { FileEntry fileEntry = getSelectedFileEntry(); if (fileEntry != null && event.type == SWT.KeyUp && (event.stateMask & SWT.CTRL) != 0) { - switch (event.character) { - case CTRL_C: // Compile Wizard - if (getCompileToolItem().isEnabled()) { - compileFileWizard(); - } - break; - case CTRL_D: // Delete file - if (getDeleteToolItem().isEnabled()) { - deleteFile(); - } - break; - case CTRL_E: // Export Wizard - exportFileWizard(); - break; - case CTRL_V: // View file - viewFile(null); - break; - } + try { + switch (event.character) { + case CTRL_C: // Compile Wizard + if (getCompileToolItem().isEnabled()) { + compileFileWizard(); + } + break; + case CTRL_D: // Delete file + if (getDeleteToolItem().isEnabled()) { + deleteFile(); + } + break; + case CTRL_E: // Export Wizard + exportFileWizard(); + break; + case CTRL_V: // View file + viewFile(null); + break; + } + } catch (DiskException e) { + DiskExplorerTab.this.diskWindow.handle(e); + } } } }; @@ -1625,39 +1691,46 @@ public class DiskExplorerTab { break; } } else { - switch (event.character) { - case CTRL_I: // Import Wizard - importFiles(); - break; - case CTRL_P: // Print... - print(); - break; - case CTRL_S: // Save - if (getSaveToolItem().isEnabled()) { - save(); - } - break; - } + try { + switch (event.character) { + case CTRL_I: // Import Wizard + importFiles(); + break; + case CTRL_P: // Print... + print(); + break; + case CTRL_S: // Save + if (getSaveToolItem().isEnabled()) { + save(); + } + break; + } + } catch (DiskException e) { + DiskExplorerTab.this.diskWindow.handle(e); + } } } else { // No CTRL key - if ((event.stateMask & SWT.ALT) != SWT.ALT) { // Ignore ALT key combinations like alt-F4! - switch (event.keyCode) { - case SWT.F2: // Standard file display - changeCurrentFormat(FormattedDisk.FILE_DISPLAY_STANDARD); - break; - case SWT.F3: // Native file display - changeCurrentFormat(FormattedDisk.FILE_DISPLAY_NATIVE); - break; - case SWT.F4: // Detail file display - changeCurrentFormat(FormattedDisk.FILE_DISPLAY_DETAIL); - break; - case SWT.F5: // Show deleted files - setShowDeletedFiles(!getShowDeletedFilesToolItem().getSelection()); - getShowDeletedFilesToolItem().setSelection(isShowDeletedFiles()); - fillFileTable(getCurrentFileList()); - break; + if ((event.stateMask & SWT.ALT) != SWT.ALT) // Ignore ALT key combinations like alt-F4! + try { + switch (event.keyCode) { + case SWT.F2: // Standard file display + changeCurrentFormat(FormattedDisk.FILE_DISPLAY_STANDARD); + break; + case SWT.F3: // Native file display + changeCurrentFormat(FormattedDisk.FILE_DISPLAY_NATIVE); + break; + case SWT.F4: // Detail file display + changeCurrentFormat(FormattedDisk.FILE_DISPLAY_DETAIL); + break; + case SWT.F5: // Show deleted files + setShowDeletedFiles(!getShowDeletedFilesToolItem().getSelection()); + getShowDeletedFilesToolItem().setSelection(isShowDeletedFiles()); + fillFileTable(getCurrentFileList()); + break; } - } + } catch (DiskException e) { + DiskExplorerTab.this.diskWindow.handle(e); + } } } } @@ -1728,7 +1801,11 @@ public class DiskExplorerTab { printFileHeaders(); gc.setFont(normalFont); println(disk.getDiskName()); - printFiles(disk, 1); + try { + printFiles(disk, 1); + } catch (DiskException e) { + DiskExplorerTab.this.diskWindow.handle(e); + } } if (y != clientArea.y) { // partial page printFooter(); @@ -1811,7 +1888,7 @@ public class DiskExplorerTab { clientArea.y + clientArea.height + dpiY - point.y); page++; } - protected void printFiles(DirectoryEntry directory, int level) { + protected void printFiles(DirectoryEntry directory, int level) throws DiskException { Iterator iterator = directory.getFiles().iterator(); while (iterator.hasNext()) { FileEntry fileEntry = (FileEntry) iterator.next(); @@ -2027,5 +2104,5 @@ public class DiskExplorerTab { protected ToolItem getShowDeletedFilesToolItem() { return showDeletedFilesToolItem; - } + } } diff --git a/src/main/java/com/webcodepro/applecommander/ui/swt/DiskWindow.java b/src/main/java/com/webcodepro/applecommander/ui/swt/DiskWindow.java index 6142bfa..5f84644 100644 --- a/src/main/java/com/webcodepro/applecommander/ui/swt/DiskWindow.java +++ b/src/main/java/com/webcodepro/applecommander/ui/swt/DiskWindow.java @@ -24,11 +24,15 @@ import org.eclipse.swt.custom.CTabFolder; import org.eclipse.swt.events.DisposeEvent; import org.eclipse.swt.events.DisposeListener; import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.widgets.MessageBox; import org.eclipse.swt.widgets.Shell; +import com.webcodepro.applecommander.storage.DiskCorruptException; +import com.webcodepro.applecommander.storage.DiskException; import com.webcodepro.applecommander.storage.FormattedDisk; import com.webcodepro.applecommander.ui.UiBundle; import com.webcodepro.applecommander.ui.swt.util.ImageManager; +import com.webcodepro.applecommander.util.TextBundle; /** * Displays disk information on the screen. @@ -46,6 +50,8 @@ public class DiskWindow { private DiskInfoTab diskInfoTab; private DiskMapTab[] diskMapTabs; + private TextBundle textBundle = UiBundle.getInstance(); + /** * Construct the disk window. */ @@ -84,6 +90,58 @@ public class DiskWindow { shell.open(); } + /** + * Warns user about a Disk Corrupt problem + * + * @param e + */ + protected void handle(final DiskCorruptException e) { + Shell finalShell = shell; + MessageBox box = new MessageBox(finalShell, SWT.ICON_ERROR | SWT.OK); + box.setText(textBundle.get("SwtAppleCommander." + e.kind + ".Title")); //$NON-NLS-1$ + box.setMessage( + textBundle.format("SwtAppleCommander.DiskCorruptException.Message", //$NON-NLS-1$ + e.imagepath + )); + box.open(); + } + + /** + * Warns user about a Generic Disk Error problem + * + * @param e + */ + protected void handle(final DiskException e) { + if (e instanceof DiskCorruptException) { + this.handle((DiskCorruptException) e); + return; + } + final MessageBox box = new MessageBox(shell, SWT.ICON_ERROR | SWT.OK | SWT.MODELESS); + box.setText(textBundle.get("SwtAppleCommander.DiskException.Title")); //$NON-NLS-1$ + box.setMessage( + textBundle.format("SwtAppleCommander.DiskException.Message", //$NON-NLS-1$ + new Object[]{e.imagepath, e.toString()} + )); + box.open(); + } + + /** + * Warns user about an Application Error problem + * + * @param e + */ + public void handle(final Exception e) { + final TextBundle textBundle = UiBundle.getInstance(); + Shell finalShell = shell; + MessageBox box = new MessageBox(finalShell, SWT.ICON_ERROR | SWT.OK); + box.setText(textBundle.get("SwtAppleCommander.UnexpectedErrorTitle")); //$NON-NLS-1$ + box.setMessage( + textBundle.get("SwtAppleCommander.UnexpectedErrorMessage" //$NON-NLS-1$ + )); + box.open(); + e.printStackTrace(); + } + /** * Set the standard AppleCommander disk window title. * This is referenced in DiskWindow as well as DiskExplorerTab. diff --git a/src/main/java/com/webcodepro/applecommander/ui/swt/SwtAppleCommander.java b/src/main/java/com/webcodepro/applecommander/ui/swt/SwtAppleCommander.java index 06f5c83..74b990e 100644 --- a/src/main/java/com/webcodepro/applecommander/ui/swt/SwtAppleCommander.java +++ b/src/main/java/com/webcodepro/applecommander/ui/swt/SwtAppleCommander.java @@ -39,6 +39,7 @@ import org.eclipse.swt.widgets.ToolItem; import com.webcodepro.applecommander.storage.Disk; import com.webcodepro.applecommander.storage.FormattedDisk; import com.webcodepro.applecommander.storage.Disk.FilenameFilter; +import com.webcodepro.applecommander.storage.DiskUnrecognizedException; import com.webcodepro.applecommander.ui.AppleCommander; import com.webcodepro.applecommander.ui.UiBundle; import com.webcodepro.applecommander.ui.UserPreferences; @@ -171,19 +172,31 @@ public class SwtAppleCommander implements Listener { try { Disk disk = new Disk(fullpath); FormattedDisk[] formattedDisks = disk.getFormattedDisks(); - if (formattedDisks != null) { - DiskWindow window = new DiskWindow(shell, formattedDisks, imageManager); - window.open(); - } else { - showUnrecognizedDiskFormatMessage(fullpath); - } + DiskWindow window = new DiskWindow(shell, formattedDisks, imageManager); + window.open(); + } catch (DiskUnrecognizedException e) { + showUnrecognizedDiskFormatMessage(fullpath); } catch (Exception ignored) { ignored.printStackTrace(); - showUnrecognizedDiskFormatMessage(fullpath); + showUnexpectedErrorMessage(fullpath); } } } + /** + * Displays the unrecognized disk format message. + * @param fullpath + */ + protected void showUnexpectedErrorMessage(String fullpath) { + Shell finalShell = shell; + MessageBox box = new MessageBox(finalShell, SWT.ICON_ERROR | SWT.OK); + box.setText(textBundle.get("SwtAppleCommander.UnexpectedErrorTitle")); //$NON-NLS-1$ + box.setMessage( + textBundle.format("SwtAppleCommander.UnexpectedErrorMessage", //$NON-NLS-1$ + fullpath)); + box.open(); + } + /** * Displays the unrecognized disk format message. * @param fullpath diff --git a/src/main/resources/com/webcodepro/applecommander/ui/UiBundle.properties b/src/main/resources/com/webcodepro/applecommander/ui/UiBundle.properties index 5742885..8e3f876 100644 --- a/src/main/resources/com/webcodepro/applecommander/ui/UiBundle.properties +++ b/src/main/resources/com/webcodepro/applecommander/ui/UiBundle.properties @@ -270,13 +270,19 @@ GraphicsFilterAdapter.BadImageMessage=Unexpected graphic file encountered\! # SwtAppleCommander SwtAppleCommander.AppleCommander=AppleCommander SwtAppleCommander.UnrecognizedFormatTitle=Unrecognized Disk Format -SwtAppleCommander.UnrecognizedFormatMessage=Unable to load "{0}".\n\nAppleCommander did not recognize the format\nof the disk. Either this is a new format\nor a protected disk.\n\nSorry\! +SwtAppleCommander.UnrecognizedFormatMessage=Unable to load "{0}".\n\nAppleCommander did not recognize the format of the disk. Either this is a new format or a protected disk.\n\nSorry\! SwtAppleCommander.OpenDiskImageTooltip=Open a disk image (Ctrl+O) SwtAppleCommander.CreateDiskImageTooltip=Create a disk image (Ctrl+C) SwtAppleCommander.CompareDiskImageTooltip=Compare two disk images (Ctrl+E) SwtAppleCommander.AboutTooltip=About AppleCommander (Ctrl+A) SwtAppleCommander.AboutTitle=About AppleCommander SwtAppleCommander.AboutMessage=AppleCommander\nVersion {0}\n{1}\n\nAppleCommander was created for the express\npurpose of assisting those-who-remember.\n\nI wish you many hours of vintage pleasure\!\n-Rob +SwtAppleCommander.UnexpectedErrorTitle=Application Error +SwtAppleCommander.UnexpectedErrorMessage=Unfortunately "{0}" triggered an unexpected application error.\n\nPlease report this to the developers.\n\nWe are terribly sorry for the inconvenience\! +SwtAppleCommander.DiskCorruptException.RecursiveDirectoryStructure.Title=Recursive Directory structure detected. +SwtAppleCommander.DiskCorruptException.Message=Unfortunately "{0}" is corrupted.\n\nYou can't use this disk safely. Please use a First Aid tool to recover your data.\n\nSorry\! +SwtAppleCommander.DiskException.Title="Disk Generic Error" +SwtAppleCommander.DiskException.Message=Unfortunately "{0}" has an unrecognizable but yet fatal error, internal code "{1}".\n\nYou can't use this disk safely.\n\nSorry\! # SwingAppleCommander SwingAppleCommander.MenuFile=File