package NET.worlds.scape; import NET.worlds.console.Console; import NET.worlds.network.URL; import java.io.ByteArrayOutputStream; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.text.MessageFormat; import java.util.Enumeration; public class DynamicForwardAttribute extends Attribute implements NonPersister, WobLoaded { WObject wob = null; static int DYNAMIC_CODE = 21990; WobLoader wobLoader; DataInputStream wobLoaderProps; private ByteArrayOutputStream _bs = new ByteArrayOutputStream(); DynamicForwardAttribute(int attrID) { super(attrID); } private URL getDynamicHeader(DataInputStream ds) { try { return ds.readUnsignedShort() != DYNAMIC_CODE ? null : new URL(this, ds.readUTF()); } catch (IOException var3) { return null; } } @Override public void setFromNetData(DataInputStream ds, int len) throws IOException { URL wobName = this.getDynamicHeader(ds); if (wobName != null && this.wob != null && wobName.equals(this.wob.getSourceURL())) { this.setProps(ds); } else { if (this.wob != null) { WObject w = this.wob; this.wob = null; w.detach(); } if (wobName == null) { ((Sharer)this.getOwner()).removeAttribute(this); return; } if (this.wobLoader == null || !this.wobLoader.getWobName().equals(wobName)) { this.wobLoader = new WobLoader(wobName, this); } this.wobLoaderProps = ds; } } @Override public void wobLoaded(WobLoader loader, SuperRoot w) { if (loader == this.wobLoader) { Object[] arguments = new Object[]{new String(loader.getWobName().toString())}; if (w == null) { Console.println(MessageFormat.format(Console.message("Couldnt-load"), arguments)); this.wobLoaderProps = null; } else if (!(w instanceof WObject)) { Console.println(MessageFormat.format(Console.message("not-WObject"), arguments)); this.wobLoaderProps = null; } else { this.wob = (WObject)w; this.wob.getSharer().createDynamicForwardedFromNet(this); ((WObject)this.getOwner().getOwner()).add(this.wob); this.setProps(this.wobLoaderProps); this.wobLoaderProps = null; } } } void connect(WObject w) { assert this.wob == null; this.wob = w; this.noteChange(); } void unconnect() { if (this.wob != null) { this.wob = null; this.noteChange(); } } public void setProps(DataInputStream ds) { while (true) { byte[] b; int id; try { if ((id = ds.read()) == -1) { return; } int len = ds.readByte(); b = new byte[len]; ds.readFully(b, 0, len); } catch (IOException var6) { Object[] arguments = new Object[]{new String("" + this.getAttrID())}; Console.println(MessageFormat.format(Console.message("Early-EOF"), arguments)); return; } this.wob.getSharer().setFromNetData(id, b); } } @Override public void generateNetData(DataOutputStream s) throws IOException { if (this.wob != null && this.wob.getSourceURL() != null) { s.writeShort(DYNAMIC_CODE); s.writeUTF(this.wob.getSourceURL().getRelativeTo(this)); Enumeration e = this.wob.getSharer().getAttributes(); while (e.hasMoreElements()) { Attribute a = (Attribute)e.nextElement(); s.writeByte(a.getAttrID()); this._bs.reset(); try { a.generateNetData(new DataOutputStream(this._bs)); } catch (IOException var5) { System.err.println(var5); throw new Error("Fatal in generateNetData"); } s.writeByte(this._bs.size()); this._bs.writeTo(s); } } } @Override protected void noteAddingTo(SuperRoot owner) { WObject w = (WObject)owner.getOwner(); if ((w.getSharer().getMode() & 1) != 0) { throw new ClassCastException("Must forward to unforwarded object"); } } @Override public void detach() { if (this.wob == null && !this._waitingForFeedback) { this.wobLoader = null; super.detach(); } else { Console.println(Console.message("Shutting-down")); if (this.wob != null) { this.wob.detach(); } } } @Override public void setAttrID(int newID) { Console.println(Console.message("Cant-change-ID")); } @Override public String toString() { return this.wob == null ? super.toString() : super.toString() + "[forwarding wob " + this.wob.getName() + "]"; } @Override public void restoreState(Restorer r) throws IOException, TooNewException { assert false; } }