1 6 7 package de.schlichtherle.io; 8 9 import de.schlichtherle.io.archive.spi.*; 10 11 import java.io.*; 12 13 26 abstract class GeneralArchiveController 27 extends ArchiveController 28 implements ArchiveEntryFactory { 29 30 33 private FileSystemState fileSystemState = new ResetFileSystem(); 34 35 36 protected GeneralArchiveController( 37 java.io.File target, 38 ArchiveController enclController, 39 String enclEntryName, 40 ArchiveDriver driver) { 41 super(target, enclController, enclEntryName, driver); 42 } 43 44 protected final ArchiveFileSystem getFileSystem(boolean autoCreate) 45 throws IOException { 46 assert readLock().isLocked() || writeLock().isLocked(); 47 return fileSystemState.getFileSystem(autoCreate); 48 } 49 50 protected final boolean isTouched() { 51 ArchiveFileSystem fileSystem = getFileSystem(); 52 return fileSystem != null && fileSystem.isTouched(); 53 } 54 55 64 protected void touch() throws IOException { 65 assert writeLock().isLocked(); 66 setScheduled(true); 67 } 68 69 protected final ArchiveFileSystem getFileSystem() { 70 return fileSystemState.getFileSystem(); 71 } 72 73 protected final void setFileSystem(ArchiveFileSystem fileSystem) { 74 fileSystemState.setFileSystem(fileSystem); 75 } 76 77 private static abstract class FileSystemState { 78 public abstract ArchiveFileSystem getFileSystem(boolean autoCreate) 79 throws IOException; 80 81 public ArchiveFileSystem getFileSystem() { 82 return null; 83 } 84 85 public abstract void setFileSystem(ArchiveFileSystem fileSystem); 86 } 88 private class ResetFileSystem extends FileSystemState { 89 public ArchiveFileSystem getFileSystem(final boolean autoCreate) 90 throws IOException { 91 try { 92 class Mounter implements IORunnable { 93 public void run() throws IOException { 94 if (fileSystemState == ResetFileSystem.this) { 98 mount(autoCreate); 99 assert fileSystemState instanceof MountedFileSystem; 100 } else { 101 assert fileSystemState != null; 102 assert !(fileSystemState instanceof ResetFileSystem); 103 } 104 } 105 } 107 runWriteLocked(new Mounter()); 108 } catch (FalsePositiveException falsePositive) { 109 if (falsePositive.isCacheable()) 122 fileSystemState = new FalsePositiveFileSystem(falsePositive); 123 throw falsePositive; 124 } 125 126 assert fileSystemState != this; 127 return fileSystemState.getFileSystem(autoCreate); 131 } 132 133 public void setFileSystem(ArchiveFileSystem fileSystem) { 134 if (fileSystem != null) 136 fileSystemState = new MountedFileSystem(fileSystem); 137 } 138 } 140 private class MountedFileSystem extends FileSystemState { 141 private final ArchiveFileSystem fileSystem; 142 143 private MountedFileSystem(final ArchiveFileSystem fileSystem) { 144 assert fileSystem != null : "It's illegal to use this state with null as the file system!"; 145 this.fileSystem = fileSystem; 146 } 147 148 public ArchiveFileSystem getFileSystem(boolean autoCreate) 149 throws IOException { 150 return fileSystem; 151 } 152 153 public ArchiveFileSystem getFileSystem() { 154 return fileSystem; 155 } 156 157 public void setFileSystem(ArchiveFileSystem fileSystem) { 158 assert fileSystem == null : "It's illegal to assign a file system to an archive controller which already has its file system mounted!"; 159 fileSystemState = new ResetFileSystem(); 160 } 161 } 163 private class FalsePositiveFileSystem extends FileSystemState { 164 private final IOException exception; 165 166 private FalsePositiveFileSystem(final IOException exception) { 167 assert exception != null : "It's illegal to use this state with null as the IOException!"; 168 this.exception = exception; 169 } 170 171 public ArchiveFileSystem getFileSystem(boolean autoCreate) 172 throws IOException { 173 throw exception; 174 } 175 176 public void setFileSystem(ArchiveFileSystem fileSystem) { 177 assert fileSystem == null : "It's illegal to assign a file system to an archive controller for a false positive archive file!"; 178 fileSystemState = new ResetFileSystem(); 179 } 180 } 182 203 protected abstract void mount(boolean autoCreate) 204 throws IOException; 205 206 protected void reset() throws IOException { 207 setFileSystem(null); 208 } 209 210 public final ArchiveEntry createArchiveEntry(String name, ArchiveEntry blueprint) 211 throws CharConversionException { 212 return getDriver().createArchiveEntry(this, name, blueprint); 213 } 214 } 215 | Popular Tags |