1 5 package org.prevayler.implementation.snapshot; 6 7 import java.io.*; 8 9 import org.prevayler.foundation.*; 10 11 12 14 public class SnapshotManager { 15 16 SnapshotManager() {} 19 20 SnapshotManager(Object newPrevalentSystem) { 21 nullInit(newPrevalentSystem); 22 } 23 24 protected void nullInit(Object newPrevalentSystem) { 26 _recoveredPrevalentSystem = newPrevalentSystem; 27 _recoveredVersion = 0; 28 _directory = null; 29 } 30 31 private File _directory; 32 private Object _recoveredPrevalentSystem; 33 private long _recoveredVersion; 34 35 36 40 public SnapshotManager(Object newPrevalentSystem, String snapshotDirectoryName) throws ClassNotFoundException , IOException { 41 init(newPrevalentSystem, snapshotDirectoryName); 42 } 43 44 48 protected void init(Object newPrevalentSystem, String snapshotDirectoryName) throws ClassNotFoundException , IOException { 49 _directory = FileManager.produceDirectory(snapshotDirectoryName); 50 _recoveredVersion = latestVersion(); 51 _recoveredPrevalentSystem = _recoveredVersion == 0 52 ? newPrevalentSystem 53 : readSnapshot(_recoveredVersion); 54 } 55 56 public Object recoveredPrevalentSystem() { return _recoveredPrevalentSystem; } 57 58 59 public long recoveredVersion() { return _recoveredVersion; } 60 61 62 public void writeSnapshot(Object prevalentSystem, long version) throws IOException { 63 File tempFile = File.createTempFile("snapshot" + version + "temp", "generatingSnapshot", _directory); 64 65 writeSnapshot(prevalentSystem, tempFile); 66 67 File permanent = snapshotFile(version); 68 permanent.delete(); 69 if (!tempFile.renameTo(permanent)) throw new IOException("Temporary snapshot file generated: " + tempFile + "\nUnable to rename it permanently to: " + permanent); 70 } 71 72 73 private void writeSnapshot(Object prevalentSystem, File snapshotFile) throws IOException { 74 OutputStream out = new FileOutputStream(snapshotFile); 75 try { 76 writeSnapshot(prevalentSystem, out); 77 } finally { 78 out.close(); 79 } 80 } 81 82 83 85 public void writeSnapshot(Object prevalentSystem, OutputStream out) throws IOException { 86 ObjectOutputStream stream = new ObjectOutputStream(out); 87 stream.writeObject(prevalentSystem); 88 } 89 90 91 93 protected String suffix() { 94 return "snapshot"; 95 } 96 97 98 100 private long latestVersion() throws IOException { 101 String [] fileNames = _directory.list(); 102 if (fileNames == null) throw new IOException("Error reading file list from directory " + _directory); 103 104 long result = 0; 105 for (int i = 0; i < fileNames.length; i++) { 106 long candidate = version(fileNames[i]); 107 if (candidate > result) result = candidate; 108 } 109 return result; 110 } 111 112 113 private Object readSnapshot(long version) throws ClassNotFoundException , IOException { 114 File snapshotFile = snapshotFile(version); 115 return readSnapshot(snapshotFile); 116 } 117 118 119 private Object readSnapshot(File snapshotFile) throws ClassNotFoundException , IOException { 120 FileInputStream in = new FileInputStream(snapshotFile); 121 try { 122 return readSnapshot(in); 123 } finally { in.close(); } 124 } 125 126 127 129 public Object readSnapshot(InputStream in) throws IOException, ClassNotFoundException { 130 ObjectInputStream ois = new ObjectInputStream(in); 131 return ois.readObject(); 132 } 133 134 135 private File snapshotFile(long version) { 136 String fileName = "0000000000000000000" + version; 137 return new File(_directory, fileName.substring(fileName.length() - 19) + "." + suffix()); 138 } 139 140 141 143 private long version(String fileName) { 144 if (!fileName.endsWith("." + suffix())) return -1; 145 return Long.parseLong(fileName.substring(0, fileName.indexOf("." + suffix()))); } 147 148 149 public Object deepCopy(Object original, String errorMessage) { 150 try { 151 ByteArrayOutputStream out = new ByteArrayOutputStream(); 152 writeSnapshot(original, out); 153 return readSnapshot(new ByteArrayInputStream(out.toByteArray())); 154 } catch (Exception ex) { 155 ex.printStackTrace(); 156 throw new RuntimeException (errorMessage); 157 } 158 } 159 160 } 161 | Popular Tags |