package NET.worlds.scape; import NET.worlds.core.IniFile; import NET.worlds.network.URL; import java.io.DataInput; import java.io.DataInputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.util.Enumeration; import java.util.Hashtable; import java.util.Vector; public class Restorer { private DataInput is; private boolean myFile; private Hashtable> classTable; private Hashtable objectTable; private Hashtable cookieTable; private URL reference; private int _version; private boolean _oldFlag; private int _dblevel = 0; private Integer _firstRead = null; public URL getReferenceURL() { return this.reference; } public final int version() { return this._version; } private Restorer(String fileName) throws IOException, BadFormatException, TooNewException { this(new DataInputStream(new FileInputStream(new File(fileName)))); if (this._dblevel > 0) { System.out.println("Restoring from " + fileName); } this.myFile = true; } public Restorer(String fileName, URL url) throws IOException, BadFormatException, TooNewException { this(fileName); this.reference = url; } public Restorer(URL url) throws IOException, BadFormatException, TooNewException { this(url.unalias(), url); } public Restorer(DataInput is) throws IOException, BadFormatException, TooNewException { this.is = is; this._dblevel = IniFile.gamma().getIniInt("RESTORE_DEBUG", 0); String header = this.restoreString(); if (header != null && header.equals("PERSISTER Worlds, Inc.")) { this._version = this.restoreInt(); if (this._dblevel > 0) { System.out.println("Persister version " + this._version + " {"); } if (this._version < 1) { throw new BadFormatException(); } else if (this._version > Saver.version()) { throw new TooNewException(); } else { this.classTable = new Hashtable>(); this.objectTable = new Hashtable(); this.cookieTable = new Hashtable(); } } else { throw new BadFormatException(); } } public Restorer(DataInput is, URL url) throws IOException, BadFormatException, TooNewException { this(is); this.reference = url; } public int restoreVersion(Object cookie) throws IOException { if (this._version == 1) { return 0; } else { Integer oldv = this.cookieTable.get(cookie); int v; if (oldv == null) { v = this.restoreInt(); this.cookieTable.put(cookie, new Integer(v)); } else { v = oldv; } return v; } } public Persister restore() throws IOException, TooNewException { return this.restore(true); } public Persister restore(boolean restoreContents) throws IOException, TooNewException { boolean firstCall = this._firstRead == null; Integer hc = new Integer(this.restoreInt()); if (this._dblevel > 0) { System.out.print("Object:" + Integer.toString(hc, 16)); } if (this.objectTable.containsKey(hc)) { Persister obj = this.objectTable.get(hc); if (this._dblevel > 0) { System.out.println(" - old: " + obj.getClass().getName() + " (" + Integer.toString(hc, 16) + ")"); } return obj; } else { Persister p = null; try { Class c = this.restoreClass(true); if (this._dblevel > 0) { System.out.println(" {"); } try { p = (Persister)c.newInstance(); } catch (NoSuchMethodError var7) { System.out.println(c); var7.printStackTrace(System.out); throw var7; } } catch (InstantiationException var8) { var8.printStackTrace(System.out); assert false; } catch (IllegalAccessException var9) { var9.printStackTrace(System.out); assert false; } this.objectTable.put(hc, p); if (restoreContents) { p.restoreState(this); } if (this._dblevel > 0) { System.out.println((restoreContents ? "} Done with: " : "} Created: ") + Integer.toString(hc, 16)); } Persister obj = this.objectTable.get(hc); if (firstCall) { this._firstRead = hc; } return obj; } } public Vector restoreVectorMaybeNull() throws IOException, TooNewException { return this.restoreBoolean() ? this.restoreVector() : null; } public Persister restoreMaybeNull() throws IOException, TooNewException { if (this.restoreBoolean()) { if (this._dblevel > 0) { System.out.println("null"); } return null; } else { return this.restore(); } } public Class restoreClass() throws IOException { return this.restoreClass(true); } public Class restoreClass(boolean printdebug) throws IOException { Class c = null; Integer classhc = new Integer(this.restoreInt()); if (this.classTable.containsKey(classhc)) { c = this.classTable.get(classhc); if (this._dblevel > 0 && printdebug) { System.out.print("..." + c.getName() + " [" + Integer.toString(classhc, 16) + "]"); } } else { String s = this.restoreString(); if (this._dblevel > 0 && printdebug) { System.out.print("---" + s + " [" + Integer.toString(classhc, 16) + "]"); } try { c = Class.forName(s); } catch (ClassNotFoundException var8) { try { if (s.equals("NET.worlds.network.World")) { if (this._dblevel > 0) { System.out.print(" (Converting NET.worlds.network.World to NET.worlds.scape.World)"); } c = Class.forName("NET.worlds.scape.World"); } else { if (this._dblevel > 0) { System.out.print(" (Converting " + s + " to NET.worlds.scape." + s + ")"); } c = Class.forName("NET.worlds.scape." + s); } } catch (ClassNotFoundException var7) { throw new Error("Can't find class " + s); } } this.classTable.put(classhc, c); } return c; } private Object makeArray(Class var1, int var2) { return java.lang.reflect.Array.newInstance(var1, var2); } public Persister[] restoreArray() throws IOException, TooNewException { Class arrayclass = null; if (this._version > 4) { arrayclass = this.restoreClass(false); } int length = this.restoreInt(); Persister[] pa = (Persister[])null; if (arrayclass == null) { if (this._dblevel > 0) { System.out.println("Array of " + Integer.toString(length, 16) + " items {"); } pa = new Persister[length]; } else { String classname = arrayclass.getName(); assert classname.startsWith("[L"); assert classname.endsWith(";"); classname = classname.substring(2); classname = classname.substring(0, classname.length() - 1); if (this._dblevel > 0) { System.out.println("Array of " + Integer.toString(length, 16) + " " + classname + " {"); } try { arrayclass = Class.forName(classname); } catch (ClassNotFoundException var6) { throw new Error("Can't find class " + classname.substring(1)); } Object ob = this.makeArray(arrayclass, length); pa = (Persister[])ob; } for (int i = 0; i < length; i++) { pa[i] = this.restoreMaybeNull(); } if (this._dblevel > 0) { System.out.println("} Done with array"); } return pa; } public Vector restoreVector() throws IOException, TooNewException { int length = this.restoreInt(); if (this._dblevel > 0) { System.out.println("Vector of " + Integer.toString(length, 16) + " items {"); } Vector v = new Vector(length); for (int i = 0; i < length; i++) { v.addElement(this.restore()); } if (this._dblevel > 0) { System.out.println("} Done with vector"); } return v; } public Vector restoreVectorSuperRoot() throws IOException, TooNewException { int length = this.restoreInt(); if (this._dblevel > 0) { System.out.println("Vector of " + Integer.toString(length, 16) + " items {"); } Vector v = new Vector(length); for (int i = 0; i < length; i++) { v.addElement((SuperRoot)this.restore()); } if (this._dblevel > 0) { System.out.println("} Done with vector"); } return v; } public Vector restoreVectorActions() throws IOException, TooNewException { int length = this.restoreInt(); if (this._dblevel > 0) { System.out.println("Vector of " + Integer.toString(length, 16) + " items {"); } Vector v = new Vector(length); for (int i = 0; i < length; i++) { v.addElement((Action)this.restore()); } if (this._dblevel > 0) { System.out.println("} Done with vector"); } return v; } public String restoreString() throws IOException { return this.restoreBoolean() ? null : this.is.readUTF(); } public boolean restoreBoolean() throws IOException { return this.is.readBoolean(); } public byte restoreByte() throws IOException { return this.is.readByte(); } public short restoreShort() throws IOException { return this.is.readShort(); } public int restoreInt() throws IOException { return this.is.readInt(); } public long restoreLong() throws IOException { return this.is.readLong(); } public float restoreFloat() throws IOException { return this.is.readFloat(); } public double restoreDouble() throws IOException { return this.is.readDouble(); } public void done() throws IOException, Error { if (this._dblevel > 0) { System.out.println("Calling all postRestores"); } Enumeration e = this.objectTable.elements(); while (e.hasMoreElements()) { Persister p = e.nextElement(); p.postRestore(this._version); } e = this.objectTable.elements(); while (e.hasMoreElements()) { Object obj = e.nextElement(); if (obj != this.objectTable.get(this._firstRead) && obj instanceof SuperRoot) { SuperRoot s = (SuperRoot)obj; if (s.getOwner() == null) { System.out.println("Warning: " + s.getName() + " was not owned by any object."); s.finalize(); } } } String trailer = this.restoreString(); if (!trailer.equals("END PERSISTER")) { throw new Error("Format error in save file"); } else { if (this.myFile) { ((DataInputStream)this.is).close(); } this.classTable = null; this.objectTable = null; this.cookieTable = null; if (this._dblevel > 0) { System.out.println("} Done with persister"); } } } public void setOldFlag() { this._oldFlag = true; if (this._dblevel > 0) { System.out.println("----OLD!----"); } } public boolean oldFlag() { return this._oldFlag; } public void replace(Persister old, Persister replacement) { System.out.println("Converting a " + old.getClass().getName() + " to a " + replacement.getClass().getName()); boolean found = false; Enumeration oe = this.objectTable.keys(); while (oe.hasMoreElements()) { Object k = oe.nextElement(); if (this.objectTable.get(k) == old) { this.objectTable.put(k, replacement); found = true; break; } } assert found; } }